You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React Native Video安卓端无法全屏播放问题求助

Android端react-native-video无法全屏播放Vimeo视频的解决方案

首先得说,你遇到的这个问题在RN 0.57.7 + react-native-video的组合里挺常见——Android端的全屏播放需要兼顾配置、布局和Orientation的协同处理,不像iOS那样开箱即用。咱们一步步来排查和修复:

一、先补全Android核心配置(最容易忽略的坑)

AndroidManifest.xml里的Activity配置是关键,如果没加屏幕旋转的相关配置,旋转时Activity会直接重启,导致视频状态丢失、全屏失效。

找到你的android/app/src/main/AndroidManifest.xml,找到对应的<activity>标签(一般是MainActivity),添加android:configChanges="keyboard|keyboardHidden|orientation|screenSize"

<activity
  android:name=".MainActivity"
  android:label="@string/app_name"
  android:configChanges="keyboard|keyboardHidden|orientation|screenSize" <!-- 新增这行 -->
  android:windowSoftInputMode="adjustResize">
  ...
</activity>

二、代码逻辑的针对性修复

1. 调整Orientation切换时机

你现在在componentDidMount里直接锁横屏,但此时用户还没点击播放,界面显示的是封面图,强制横屏不仅体验奇怪,还可能导致后续播放的布局适配异常。应该改成用户点击播放时再切换横屏,退出时切回竖屏:

修改播放按钮的点击事件:

<TouchableOpacity onPress={() => {
  this.setState({playing:true});
  Orientation.lockToLandscape(); // 点击播放才切换横屏
}} >
  <Image source={require("../assets/Common/Play/playIcon.png")}/>
</TouchableOpacity>

同时优化返回按钮的逻辑,先重置播放状态再切竖屏:

goToHome(){
  this.setState({playing: false}); // 先停止播放
  Orientation.lockToPortrait();
  this.props.navigation.goBack();
}

2. 筛选Android兼容的Vimeo视频链接

Vimeo返回的files数组里可能包含Android不支持的格式(比如webm),直接取第一个链接可能刚好是iOS优先的格式,导致Android播放异常。咱们筛选出MP4格式的视频,优先选高清版本:

修改fetchVimeoVideo里的文件处理逻辑:

const jsonResponse = await response.json();
let { files} = jsonResponse;
if (response.status != 200) {
  alert(response.status)
}
// 筛选MP4格式,按画质从高到低排序,取第一个
const androidCompatibleVideo = files
  .filter(file => file.type === 'video/mp4')
  .sort((a, b) => b.quality - a.quality)[0];
// 找不到MP4的话 fallback 到原数组第一个
const targetVideo = androidCompatibleVideo ? [androidCompatibleVideo] : [files[0]];
await this.setState({ videoFileArr: targetVideo, loading: false });

3. 优化Video组件的配置与布局

你当前的Video组件缺少两个关键配置,布局样式也可以调整得更适配横竖屏:

  • 添加resizeMode="cover":确保视频填充整个屏幕,避免黑边
  • 添加onFullscreen回调:同步全屏状态与Orientation
  • flex:1代替绝对定位,让视频自动适配屏幕尺寸

修改后的Video组件:

<Video 
  source={{ uri: this.state.videoFileArr[0].link}} 
  ref={ ref => this.player = ref } 
  onBuffer={this.onBuffer} 
  onError={this.videoError} 
  style={styles.backgroundVideo} 
  controls={true} 
  paused={false} 
  fullscreen={true}
  resizeMode="cover" // 确保视频填充屏幕
  onFullscreen={(isFullscreen) => {
    // 同步全屏状态和Orientation
    if (isFullscreen) {
      Orientation.lockToLandscape();
    } else {
      Orientation.lockToPortrait();
      this.setState({playing: false});
    }
  }}
/>

对应的样式调整:

const styles = StyleSheet.create({
  container:{
    flex: 1,
  },
  backgroundVideo: {
    flex: 1,
    width: '100%',
    height: '100%',
  },
});

4. 消除SafeAreaView的影响

SafeAreaView在横屏时会自动添加左右padding,导致视频无法真正全屏。可以根据播放状态动态调整它的样式:

<SafeAreaView style={{ flex: 1, padding: this.state.playing ? 0 : undefined }}>
  ...
</SafeAreaView>

三、最后验证

做完这些修改后,建议先清理Android缓存再重新编译:

cd android && ./gradlew clean && cd .. && react-native run-android

点击播放按钮后,应该会自动切换到横屏,视频填满整个屏幕,控件正常显示;点击返回按钮会切回竖屏,回到之前的界面。

内容的提问来源于stack exchange,提问作者Sahadev

火山引擎 最新活动