如何使用react-native-video

January 11, 2020 ... ☕️ 5 min read

移动端使用React-native使用视频插件,可选择的播放器很少。而且要找到适合的不容易。使用最多的是react-native-video

总体来说,这个视频组件的功能还是比较全的。

主要特点

  • 支持格式:mp4、m3u8(需要视频h264,音频aac-lc);
  • 属性功能:暂停/继续、音量控制、拖拽进度、全屏、后台播放等;
  • 实例方法:保存视频、控制播放进度(seek);
  • 事件回调:视频加载/失败、拖拽、速率变动、进度等。

常见问题及解决方法

实例方法太少,除了播放进度控制以外,只能修改播放器属性

组件内部使用了react-native-dom,这个库旨在让react和react-native互通,即使用同一套代码,编译到两个平台。所以react-native-video是在这个思路上做的,使用video标签,并扩展了一些方法,然后添加一些link代码,通过调用设备(Android、iOS或windows平台)播放器,达到播放视频的目的。

所以感觉是为了稳定性(毕竟播放器状况太多),牺牲了一些自定义功能。

如果想要切换播放源/码率/播放速度等,需要手动控制这些对应的prop属性。在代码里就是层层的callback,或者直接使用存储器。

// source: { uri: 'https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4' }
const [source, setSource] = useState({});

useEffect(() => {
  setSource({...props.source});
}, [props.source]);

<Video
  onEnd={onEnd}
  onLoad={onLoad}
  onLoadStart={onLoadStart}
  onProgress={onProgress}
  paused={paused}
  ref={ref => (videoPlayer = ref)}
  resizeMode="cover"
  source={source}
  style={styles.mediaPlayer}
  volume={0.0}
/>

如果嵌套过深,想通过ref来达到修改播放器属性(例如source、paused等)的目的,也不是不可以……

使用setNativeProps

setNativeProps用于绕过复合(composite component)组件,直接修改native标签的属性。所以调用的必须是native标签或者forwardRef过来的标签(ref)。

所以在Video的ref上调用这个方法,就相当于直接修改了标签属性。

绕过了复合组件,但是事件和方法,是通过Video这个复合组件的。需要通过在seek方法里重置播放源,来达到播放的目的。

缺点:只适合有一个视频地址的播放需求。如果切换,需要同时手动重置duration、currentTime等属性。

另外,因为第二次更改,如果视频无效,不会调用load/loadStart,导致虽然视频地址是失效的,但是还在播放上一个视频。

事件函数的一般调用过程:

onLoadStart -> onLoad -> onBuffer -> onPaused(PLAYING)

const player = ref.current;
player.setNativeProps({
  paused: !videoAddress,
  src: {
    isNetwork: true,
    uri: videoAddress,
    type: "",
  }
});
player.seek(0);

注意,播放器需要一层一层forwardRef。

播放控制器不支持定制,需要手动引用其他控制器

切换皮肤,可以使用react-native-media-controls等npm包,当然也不支持自定义,只是换皮。如果想添加一些音量控制/码率控制之类的,就要手动拿出来魔改。

#react#react-native