ReactNative系列【视频支持】

2019-05-15  本文已影响0人  老鱼_chaimyu

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

项目使用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/

上一篇下一篇

猜你喜欢

热点阅读