首页 > 解决方案 > 如何让迷你控制器出现在 iOS 的 react-native-google-cast 中?

问题描述

我在启用扩展控件的 React Native 应用程序中设置了 react-native-google-cast。该文档暗示(此处此处)迷你控制器应自动出现。包中只有一个组件:CastButton。我在 AppDelegte.m 中启用了 useDefaultExpandedMediaControls,并且在投射开始时会出现展开的控件。一旦展开的控件被解除,就不会出现迷你控制器。

更新:尚未实施

在 Google Cast Github 上关注此问题。

一个好的撒玛利亚人已经发布了在 Typescript中重新实现的方法。

我将把这段代码留在这里以帮助其他人开始......

代码

包.json:

{
  "name": "iosvideo",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint ."
  },
  "dependencies": {
    "react": "17.0.1",
    "react-dom": "^17.0.2",
    "react-native": "0.64.1",
    "react-native-base64": "^0.2.1",
    "react-native-google-cast": "^4.0.3",
    "react-native-web": "^0.16.2"
  },
  "devDependencies": {
    "@babel/core": "^7.12.9",
    "@babel/runtime": "^7.12.5",
    "@react-native-community/eslint-config": "^2.0.0",
    "babel-jest": "^26.6.3",
    "babel-plugin-react-native-web": "^0.16.2",
    "eslint": "7.14.0",
    "jest": "^26.6.3",
    "metro-react-native-babel-preset": "^0.64.0",
    "react-test-renderer": "17.0.1"
  },
  "jest": {
    "preset": "react-native"
  }
}

应用程序.js:

注意:我使用HLS-Proxy来处理 HLS CORS。

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React from 'react';
import {
  SafeAreaView,
  StatusBar,
} from 'react-native';

import base64 from 'react-native-base64';

import GoogleCast, { CastButton, useRemoteMediaClient } from 'react-native-google-cast';

const App = () => {

  const client = useRemoteMediaClient();

  const getProxyUrl = function(url) {

    const proxy_url = 'http://192.168.2.220:10000';
    const video_url = base64.encode(url);
    const file_extension = '.m3u8';
    const hls_proxy_url = `${proxy_url}/${video_url}${file_extension}`;

    return hls_proxy_url;

  };

  if (client) {
    client.loadMedia({
      mediaInfo: {
        contentUrl:
          getProxyUrl('http://qthttp.apple.com.edgesuite.net/1010qwoeiuryfg/sl'),
        contentType: 'video/m3u',
        metadata: {
          title: 'Apple Event',
          type: 'generic',
        },
        streamDuration: 0,
      },
      startTime: 10, // seconds
    });
    GoogleCast.showExpandedControls();
  }

  return (
    <>
      <SafeAreaView>
        <StatusBar/>
        <CastButton style={{width: 24, height: 24, tintColor: 'black', alignSelf: 'flex-end', marginHorizontal: 8}} />
      </SafeAreaView>
    </>
  );
};

export default App;

AppDelegate.m:

#import "AppDelegate.h"

...

#import <GoogleCast/GoogleCast.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
#ifdef FB_SONARKIT_ENABLED
  InitializeFlipper(application);
#endif

  // https://github.com/facebook/react-native/issues/16376#issuecomment-810094592

  NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.js" fallbackResource:nil];

  RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:jsCodeLocation
                                              moduleProvider:nil
                                               launchOptions:launchOptions];
  #if RCT_DEV
   [bridge moduleForClass:[RCTDevLoadingView class]];
  #endif

  // END

  // RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
                                                   moduleName:@"iosVideo"
                                            initialProperties:nil];

  if (@available(iOS 13.0, *)) {
      rootView.backgroundColor = [UIColor systemBackgroundColor];
  } else {
      rootView.backgroundColor = [UIColor whiteColor];
  }

  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];

  NSString *receiverAppID = @"XXXXXXX";

  GCKDiscoveryCriteria *criteria = [[GCKDiscoveryCriteria alloc] initWithApplicationID:receiverAppID];
  GCKCastOptions* options = [[GCKCastOptions alloc] initWithDiscoveryCriteria:criteria];
  [GCKCastContext setSharedInstanceWithOptions:options];
  [GCKCastContext sharedInstance].useDefaultExpandedMediaControls = true;

  return YES;
}

...

Google Cast SDK 文档指出

在 CAF 中,框架提供了一个控制栏 GCKUIMiniMediaControlsViewController,您可以将其添加到要显示持久控件的场景中。有两种方法可以将迷你控制器添加到发件人应用程序:

让 Cast 框架通过使用 GCKUICastContainerViewController 包装现有视图控制器并在其视图底部添加 GCKUIMiniMediaControlsViewController 来管理迷你控制器的布局。

通过使用 -[createMiniMediaControlsViewController] 创建 GCKUIMiniMediaControlsViewController 实例,然后将其作为子视图添加到容器视图控制器中,将迷你控制器直接添加到现有视图控制器。

我认为这是在 React Native 库中实现的,但也许我错过了一步?

标签: iosreact-nativereact-native-google-cast

解决方案


推荐阅读