美文网首页
ReactNative系列【视频支持】

ReactNative系列【视频支持】

作者: 老鱼_chaimyu | 来源:发表于2019-05-15 00:52 被阅读0次

    项目需要实现简单视频编辑(如合并、划线、字幕等),视频播放功能。

    项目使用React Native + expo,怀疑一些视频功能不太好实现,查找资料中。

    expo video

    expo带了视频组件,可以播放视频,这可能是最简单的方式了。

    import { Video } from 'expo';
    
    export default class Test extends Component<Props> {
      constructor(props) {
        super(props);
      }
    
      render() {
        return (
          <Video
            source={{ uri: 'http://d23dyxeqlo5psv.cloudfront.net/big_buck_bunny.mp4' }}
            rate={1.0}
            volume={1.0}
            isMuted={false}
            resizeMode="cover"
            shouldPlay
            isLooping
            style={{height: 300 }}
          />
        );
      }
    }
    

    播放界面如下:


    image.png

    如果播放本地文件,需要使用以下语句:

            source={ require('../assets/background.mp4') }
    

    expo视频更多文档在此:https://docs.expo.io/versions/v32.0.0/sdk/av/


    react-native-video

    Github地址:https://github.com/react-native-community/react-native-video

    这是个视频播放组件,似乎功能有些不够,先试用下。

    安装

    Chaim:scibene-app Chaim$ yarn add react-native-video
    

    执行出错,如下:

    TypeError: TypeError: TypeError: undefined is not an object (evaluating 'RCTVideoInstance.Constants')
    
    This error is located at:
        in Video (at test.js:31)
        in Test (created by SceneView)
        in SceneView (at StackViewLayout.js:797)
        in RCTView (at View.js:44)
        in AnimatedComponent (at StackViewCard.js:69)
        in RCTView (at View.js:44)
        in AnimatedComponent (at screens.native.js:59)
        in Screen (at StackViewCard.js:57)
        in Card (at createPointerEventsContainer.js:27)
        in Container (at StackViewLayout.js:862)
        in RCTView (at View.js:44)
        in ScreenContainer (at StackViewLayout.js:313)
        in RCTView (at View.js:44)
        in AnimatedComponent (at StackViewLayout.js:309)
        in Handler (at StackViewLayout.js:302)
        in StackViewLayout (at withOrientation.js:30)
        in withOrientation (at StackView.js:79)
        in RCTView (at View.js:44)
        in Transitioner (at StackView.js:22)
        in StackView (created by Navigator)
        in Navigator (at createKeyboardAwareNavigator.js:12)
        in KeyboardAwareNavigator (at createAppContainer.js:387)
        in NavigationContainer (at createAppContainer.js:387)
        in NavigationContainer (at App.js:10)
        in App (at withExpoRoot.js:22)
        in RootErrorBoundary (at withExpoRoot.js:21)
        in ExpoRootComponent (at renderApplication.js:34)
        in RCTView (at View.js:44)
        in RCTView (at View.js:44)
        in AppContainer (at renderApplication.js:33)
    

    应该是使用expo,无法链接到视频组件。

    查了下expo资料,如果要使用本地库而非expo库,不能使用托管模式,需要先detach。


    expo detach

    Chaim:scibene-app Chaim$ npm install -g exp
    

    detach

    Chaim:scibene-app Chaim$ exp detach
    We've built a brand new CLI for Expo!
    Expo CLI is a drop in replacement for exp.
    Install: npm install -g expo-cli
    Use: expo --help
    Read more: https://blog.expo.io/expo-cli-2-0-released-a7a9c250e99c
    [19:11:10] Making sure project is set up correctly...
    [19:11:14] Your project looks good!
    Validating project manifest...
    You have not specified a custom scheme for deep linking. A default value of expb494d21628f54a23ae19c904ef84f5d9 will be used. You can change this later by following the instructions in this guide: https://docs.expo.io/versions/latest/workflow/linking
    Creating ExpoKit workspace at /Users/Chaim/Documents/workspace/scibene/scibene-app/ios...
    Downloading iOS code...
    Moving iOS project files...
    Attempting to create project directory...
    Created project directory! Copying files:
    Naming iOS project...
    Configuring iOS dependencies...
    Configuring iOS project...
    { buildPhase: 'configuring NSBundle' } 'Modifying NSBundle configuration at /Users/Chaim/Documents/workspace/scibene/scibene-app/ios/scibene2019/Supporting...'
    We added some permissions keys to `Info.plist` in your detached iOS project:
      NSCalendarsUsageDescription
      NSMotionUsageDescription
      NSCameraUsageDescription
      NSMicrophoneUsageDescription
      NSRemindersUsageDescription
      NSPhotoLibraryAddUsageDescription
      NSContactsUsageDescription
      NSPhotoLibraryUsageDescription
      NSLocationWhenInUseUsageDescription
    You may want to revise them to include language appropriate to your project. You can also remove them if your app will never use the corresponding API. See the Apple docs for these keys.
    { buildPhase: 'configuring NSBundle' } 'Using standalone config:' { manifestUrl: 'exp://exp.host/@freeworld/Scibene2019',
      isShell: true,
      releaseChannel: 'default',
      isManifestVerificationBypassed: true }
    Your iOS ExpoKit project will not contain an .entitlements file by default. If you need specific Apple entitlements, enable them manually via Xcode or the Apple Developer website.
    { buildPhase: 'configuring NSBundle' } 'Configuring iOS Launch Screen...'
    <<CCGGCCoolloorr  00xx77ffccf559b4ba000049a000>>  [[<<CCGGCCoolloorrSSppaaccee  00xx77ffccf559b4880092e02e00>>  ((kkCCGGCCoolloorrSSppaacceeDDeevviicceeRRGGBB))]]  ((  00  00  00  11  ))
    
    <CGColor 0x7ffb97e02ca0> [<CGColorSpace 0x7ffb9ab061b0> (kCGColorSpaceDeviceRGB)] ( 0 0 0 1 )
    <CGColor 0x7fe379b01070> [<CGColorSpace <0CxG7Cfoel3o7r8 400x07af8806>c c(2k0C0G8C3o0l>o r[S<pCaGcCeoDleovriScpeaRcGeB )0]x 7(f 806 c0a 400 91a 8)0
    > (kCGColorSpaceDeviceRGB)] ( 0 0 0 1 )
    <CG<CGColor 0x7fb5945006b0> [<CGColorSpace 0x7fb59470e580> (kCGColorSpaceDeviceRGB)] ( 0 0 0 1 )
    Color 0x7fac4b300bd0> [<CGColorSpace 0x7fac49509420> (kCGColorSpaceDeviceRGB)] ( 0 0 0 1 )
    <CGColor 0x7ffcf500e9f0> [<CGColorSpace 0x7ffcf3505660> (kCGColorSpaceDeviceRGB)] ( 0 0 0 1 )
    <CGColor 0x<CGColor 0x7f802ef09670> [<CGColorSpace 0x7f8037ff7c3709480> [<0CG1C0ocl2o7r0S>p a(ckeC G0Cxo7lfofr7Scp3a4c0e1Dde8v0i>c e(RkGCBG)C]o l(o r0S p0a c0e D1e v)i
    ceRGB)] ( 0 0 0 1 )
    { buildPhase: 'configuring NSBundle' } 'Cleaning up iOS...'
    iOS detach is complete!
    Moving Android project files...
    Downloading Android code...
    { buildPhase: 'copying initial shell app files' } 'Warning: Could not copy run.sh to shell app directory.'
    { buildPhase: 'copying initial shell app files' } 'Warning: Could not copy maven to shell app directory.'
    Updating Android app...
    { buildPhase: 'running shell app modifications' } 'Warning: No config file specified.'
    [19:11:28] ENOENT: no such file or directory, open '/Users/Chaim/Documents/workspace/scibene/scibene-app/android/run.sh'
    [19:11:28] Set EXPO_DEBUG=true in your env to view the stack trace.
    

    提示ios detach成功,但android出错了,先不管吧,先用ios!

    在项目目录下看到熟悉的ios和android目录了,是复杂了还是简单了呢?

    按照expo文档,detach后原有功能都不受影响,只是使用本地库的功能会无法在Expo中使用了。

    CocoaPods

    CocoaPods专门用来管理本地库,ExpoKit项目使用CocoaPods管理其依赖关系。

    Chaim:scibene-app Chaim$ sudo gem install cocoapods
    Chaim:scibene-app Chaim$ cd ios
    Chaim:ios Chaim$ pod install
    

    出错:

    Pre-downloading: `ExpoKit` from `http://github.com/expo/expo.git`, tag `ios/2.10.6`
    
    [!] Error installing ExpoKit
    [!] Failed to download 'ExpoKit': [!] /usr/local/bin/git clone http://github.com/expo/expo.git /var/folders/jy/kcxg5_w55k78gclq0ch8v_w40000gn/T/d20190514-40017-ciuamg --template= --single-branch --depth 1 --branch ios/2.10.6
    
    Cloning into '/var/folders/jy/kcxg5_w55k78gclq0ch8v_w40000gn/T/d20190514-40017-ciuamg'...
    warning: redirecting to https://github.com/expo/expo.git/
    Note: checking out '0549ad30dfce8e81c408b80f41bbb204f234bf5d'.
    
    You are in 'detached HEAD' state. You can look around, make experimental
    changes and commit them, and you can discard any commits you make in this
    state without impacting any branches by performing another checkout.
    
    If you want to create a new branch to retain commits you create, you may
    do so (now or later) by using -b with the checkout command again. Example:
    
      git checkout -b <new-branch-name>
    
    git-lfs filter-process: git-lfs: command not found
    fatal: The remote end hung up unexpectedly
    warning: Clone succeeded, but checkout failed.
    You can inspect what was checked out with 'git status'
    and retry the checkout with 'git checkout -f HEAD'
    

    解决方案一

    brew install git-lfs
    git lfs install
    pod update again
    

    结果:

    Fetching podspec for `yoga` from `../node_modules/react-native/ReactCommon/yoga`
    [!] Unable to find a specification for `EXTaskManagerInterface` depended upon by `EXLocation`
    
    You have either:
     * out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`.
     * mistyped the name or version.
     * not added the source repo that hosts the Podspec to your Podfile.
    
    Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.
    

    似乎是进一步了,按提示操作试试:

    Chaim:ios Chaim$ pod repo update
    Updating spec repo `master`
      $ /usr/local/bin/git -C /Users/Chaim/.cocoapods/repos/master fetch origin --progress
      remote: Enumerating objects: 114, done.        
      remote: Counting objects: 100% (114/114), done.        
      remote: Compressing objects: 100% (41/41), done.        
      remote: Total 81 (delta 49), reused 69 (delta 37), pack-reused 0        
      From https://github.com/CocoaPods/Specs
         bcc5c6f4477..1b71e5cb17e  master     -> origin/master
      $ /usr/local/bin/git -C /Users/Chaim/.cocoapods/repos/master rev-parse --abbrev-ref HEAD
      master
      $ /usr/local/bin/git -C /Users/Chaim/.cocoapods/repos/master reset --hard origin/master
      HEAD is now at 1b71e5cb17e [Add] YQBaseViewController 1.0
    
    CocoaPods 1.7.0.rc.1 is available.
    To update use: `sudo gem install cocoapods --pre`
    [!] This is a test version we'd love you to try.
    
    For more information, see https://blog.cocoapods.org and the CHANGELOG for this version at https://github.com/CocoaPods/CocoaPods/releases/tag/1.7.0.rc.1
    

    还是出错,换种方式:

    Chaim:ios Chaim$ pod install --repo-update
    

    一样的错误:

    Fetching podspec for `yoga` from `../node_modules/react-native/ReactCommon/yoga`
    [!] Unable to find a specification for `EXTaskManagerInterface` depended upon by `EXLocation`
    

    解决方案二

    有文章说exp不再维护了,用这些软件就是各种不可预知问题

    增加以下行到Podfile

      pod 'EXTaskManager',
        :path => "../node_modules/expo-task-manager/ios"
      pod 'EXTaskManagerInterface',
        :path => "../node_modules/expo-task-manager-interface/ios"
      pod 'EXAppLoaderProvider',
        :path => "../node_modules/expo-app-loader-provider/ios"
    

    又出其它错误:

    Installing FBAudienceNetwork (4.99.0)
    
    [!] Error installing FBAudienceNetwork
    

    查找半天,说要命令行翻墙,码农都不容易了,曹...

    翻墙设置

    vi ~/.bash_profile
    # my proxy
    alias proxy='export http_proxy=127.0.0.1:1081;export https_proxy=$http_proxy' 
    alias proxyOff='unset http_proxy;unset https_proxy'
    

    配置生效

    Chaim:ios Chaim$ source ~/.bash_profile
    Chaim:ios Chaim$ proxy
    Chaim:ios Chaim$ echo $http_proxy
    127.0.0.1:1087
    Chaim:ios Chaim$ curl -I https://google.com
    HTTP/1.1 200 Connection established
    

    配置git

    查看代理
    Chaim:ios Chaim$ git config --global http.proxy
    Chaim:ios Chaim$ git config --global https.proxy
    
    设置代理
    Chaim:ios Chaim$ git config --global http.proxy http://127.0.0.1:1087
    Chaim:ios Chaim$ git config --global https.proxy http://127.0.0.1:1087
    
    取消代理
    git config --global --unset http.proxy
    git config --global --unset https.proxy
    

    继续刚才的“pod install”,一堆"FBxxx"相关的库终于安装成功了!

    没完没了的错误:

    Generating Pods project
    [!] An error occurred while processing the post-install hook of the Podfile.
    
    undefined method `native_target' for <Pod::PodTarget name=Amplitude-iOS >:Pod::PodTarget
    

    继续没完没了的解决:

    sudo gem uninstall cocoapods
    say Y when it asks whether to remove executables
    sudo gem install cocoapods -v 1.5.3
    

    终于安装成功了,整了一下午

    Installing yoga (0.57.1.React)
    Generating Pods project
    Integrating client project
    Sending stats
    Pod installation complete! There are 53 dependencies from the Podfile and 63 total pods installed.
    

    然后Xcode打开项目,编译照样出错:

    ld: library not found for -lAmplitude-iOS
    

    无语了,只能重新开新项目试试!

    expo eject

    然后把expo的环境弄坏了,设了代理的情况下还出错,在没代理的命令行下重新安装expo-cli

    Chaim:scibene-app Chaim$ expo -V
    2.17.2
    

    此方法测试一遍,不行就不用expo了

    Install the latest version of the Expo CLI:
    npm install -g expo-cli
    Reference: https://docs.expo.io/versions/v32.0.0/introduction/installation/
    
    Create a new Expo project:
    expo init
    Reference: https://docs.expo.io/versions/v32.0.0/workflow/up-and-running/ 1
    
    Eject to ExpoKit:
    expo eject
    Reference: https://docs.expo.io/versions/v32.0.0/expokit/eject/
    
    Install Pods and copy the Podfile
    cd ios
    pod install
    cp ./Podfile <EXISTING_PROJECT>/ios/Podfile
    Reference (Step 3): https://docs.expo.io/versions/v32.0.0/expokit/expokit/ 7
    
    Change the Podfile target:
    target '<YOUR_EXISTING_TARGET>' do
    
    Make sure to update the Podfile with any existing, custom Pods.
    
    

    还是“Amplitude”库错误,查了一下这是个事件跟踪之类的库Amplitude

    几经周折,找到原因居然是这个

    are you sure you've opened the.xcworkspace file (instead of the .xcodeproj which doesn't see pods)?
    

    在新建的项目中是成功的在Xcode中打开expo eject后的项目并运行了!

    直接运行提示如下:


    image.png

    还需要运行expo客户,先启动expo,再从Xcode启动程序,才能成功,显示如下:

    Chaim:ios Chaim$ yarn start
    yarn run v1.15.2
    $ expo start
    Starting project at /Users/Chaim/Documents/workspace/scibene/expo-eject/expo1
    Expo DevTools is running at http://localhost:19002
    Starting Metro Bundler on port 19001.
    Tunnel ready.
    Your native app is running at expe9d5ccdaf75347bb80a7f63c3eabb46f://192.168.3.29:19000
    Logs for your project will appear below. Press Ctrl+C to exit.
    Finished building JavaScript bundle in 2525ms.
    Running application on iPhone XR.
    

    弄了这么久,只是打开文件错了...... 继续刚才的react-native-video操作:

    Chaim:scibene-app Chaim$ react-native link react-native-video
    rnpm-install info Linking react-native-video ios dependency 
    rnpm-install info Platform 'ios' module react-native-video has been successfully linked 
    rnpm-install info Linking react-native-video android dependency 
    rnpm-install info Platform 'android' module react-native-video has been successfully linked 
    

    还是环境问题折腾人,来个成功的福利图


    image.png

    代码如下:

    import Video from 'react-native-video';
    
      render() {
        return (
          <Video
            source={ require('../assets/background.mp4') }
            style={{height: 600 }}
          />
        );
      }
    

    react-native-video-processing

    https://github.com/shahen94/react-native-video-processing

    安装

    Chaim:scibene-app Chaim$ yarn add react-native-video-processing
    

    编译时出现swift错误,没解决


    react-native-video-editor

    https://github.com/MostWantIT/react-native-video-editor

    好像只做了视频合并


    react-native-video-editing

    安装

    Chaim:scibene-app Chaim$ yarn add react-native-video-editing
    

    直接支持react-native link

    Chaim:scibene-app Chaim$ react-native link react-native-video-editing
    
    Chaim:scibene-app Chaim$ cd ios
    Chaim:ios Chaim$ pod install
    

    用以上方式编译会出错,手动添加也出错,如下:

    'React/RCTDefines.h' file not found. 
    

    找了很久,没找到靠谱解决方案,增加以下目录到“Header search path”

    scibene-app/ios/Pods/Headers/Public
    

    但很多头文件在这个目录下并没有,简单粗暴的把找不到的头文件全部直接拷贝到此目录,编译通过了!

    正常来说头文件不变的话在哪个位置也没问题,但是如果变化了可能未知问题没法查了,把这些文件给软链接过来吧。

    ln -s ./node_modules/react-native/React/Views/*.h ./ios/Pods/Headers/Public/React/
    ln -s ./node_modules/react-native/React/Base/*.h ./ios/Pods/Headers/Public/React/
    

    终于可以视频处理了,弄了整整一天多!

    import VideoEditing from 'react-native-video-editing';
    
    // options For Audio Video Motion Filter
    const option = {
          video: {
            source: require('../assets/background.mp4'),
          },
          audio: {
            source:require('../assets/hello.mp3')
          },
          motion: VideoEditing.FILTER_SPEED_4X_FAST,
          videoQuality: VideoEditing.QUALITY_1280x720,
          audioMatched:false,
          duration: 5.5,
        }
     
    /**
     * The first arg is the options object for customization ,
     * The second and third arg is the callback which sends Error and Sucess.
     */
    
    VideoEditing.videoMotionFilter(option).then((newSource)=>{
          console.log('Success : ' + newSource);
        }).catch((error)=>{
          console.log('Error: ' + error);
        })
    

    这个组件的音视频合并、视频质量都可以调节,但似乎速度没有效果。

    看了下代码,根本就没处理速度这些参数,不过提供了这个示例应该可以直接调用吧!

    参考

    Expo文档

    https://www.jianshu.com/p/b682274cf20c

    https://www.cnblogs.com/gdsblog/p/8595206.html

    detach相关

    https://www.cnblogs.com/gdsblog/p/8573042.html

    https://www.cnblogs.com/gdsblog/p/8576936.html

    https://cocoapods.org/

    折腾很久的pod install问题

    https://github.com/expo/expo-cli/issues/289

    https://forums.expo.io/t/cant-build-sdk-32-expokit/18894/5

    https://github.com/felix-cao/Blog/issues/81

    https://github.com/CocoaPods/CocoaPods/issues/8138

    expo音视频录制

    https://www.smashingmagazine.com/2018/04/audio-video-recording-react-native-expo/

    相关文章

      网友评论

          本文标题:ReactNative系列【视频支持】

          本文链接:https://www.haomeiwen.com/subject/macraqtx.html