You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何处理expo-av视频组件加载时的网络断开重连问题

解决思路

1. 监听网络状态,恢复时重新加载视频

使用expo-netinfo监听网络连接状态,当网络从断开恢复为连接时,调用视频实例的reloadAsync()方法重新加载视频资源。

先安装依赖(未安装时执行):

npx expo install expo-netinfo

修改后的组件代码:

import { NetInfo } from 'expo-netinfo';
import { Video, ResizeMode } from 'expo-av';
import { useEffect, useRef, useState } from 'react';
import { Dimensions } from 'react-native';

const { windowWidth, windowHeight } = Dimensions.get('window');

export default function VideoView(props: any) {
  const { question } = props;
  const videoRef = useRef(null);
  const [isConnected, setIsConnected] = useState(true);

  useEffect(() => {
    const unsubscribe = NetInfo.addEventListener(state => {
      const wasConnected = isConnected;
      setIsConnected(state.isConnected);
      // 网络从断开恢复时,触发视频重新加载
      if (!wasConnected && state.isConnected && videoRef.current) {
        videoRef.current.reloadAsync();
      }
    });

    return () => unsubscribe();
  }, [isConnected]);

  return (
    <Video
      videoStyle={{ marginHorizontal: 10 }}
      source={{ uri: question.video_url }}
      rate={1.0}
      volume={1.0}
      isMuted={false}
      resizeMode={ResizeMode.CONTAIN}
      shouldPlay
      ref={videoRef}
      style={{ width: windowWidth, height: windowHeight }}
    />
  );
}

2. 捕获视频加载错误,结合网络状态重试

通过Video组件的onError回调捕获网络类加载错误,记录错误状态,待网络恢复时触发重新加载。

代码示例:

import { NetInfo } from 'expo-netinfo';
import { Video, ResizeMode } from 'expo-av';
import { useEffect, useRef, useState } from 'react';
import { Dimensions } from 'react-native';

const { windowWidth, windowHeight } = Dimensions.get('window');

export default function VideoView(props: any) {
  const { question } = props;
  const videoRef = useRef(null);
  const [isConnected, setIsConnected] = useState(true);
  const [hasLoadError, setHasLoadError] = useState(false);

  useEffect(() => {
    const unsubscribe = NetInfo.addEventListener(state => {
      const wasConnected = isConnected;
      setIsConnected(state.isConnected);
      // 网络恢复且之前存在加载错误时,重新加载视频
      if (!wasConnected && state.isConnected && hasLoadError && videoRef.current) {
        videoRef.current.reloadAsync();
        setHasLoadError(false);
      }
    });

    return () => unsubscribe();
  }, [isConnected, hasLoadError]);

  const handleVideoError = (error) => {
    // 根据错误信息判断是否为网络相关错误
    if (error.message.includes('network') || error.code === 'E_NETWORK') {
      setHasLoadError(true);
    }
  };

  return (
    <Video
      videoStyle={{ marginHorizontal: 10 }}
      source={{ uri: question.video_url }}
      rate={1.0}
      volume={1.0}
      isMuted={false}
      resizeMode={ResizeMode.CONTAIN}
      shouldPlay
      ref={videoRef}
      style={{ width: windowWidth, height: windowHeight }}
      onError={handleVideoError}
    />
  );
}

3. 重置视频源触发重新加载

如果reloadAsync()不生效,可以将视频source存入state,网络恢复时重新设置source(添加时间戳避免缓存),触发组件重新渲染加载。

代码示例:

import { NetInfo } from 'expo-netinfo';
import { Video, ResizeMode } from 'expo-av';
import { useEffect, useRef, useState } from 'react';
import { Dimensions } from 'react-native';

const { windowWidth, windowHeight } = Dimensions.get('window');

export default function VideoView(props: any) {
  const { question } = props;
  const videoRef = useRef(null);
  const [isConnected, setIsConnected] = useState(true);
  const [videoSource, setVideoSource] = useState({ uri: question.video_url });

  useEffect(() => {
    const unsubscribe = NetInfo.addEventListener(state => {
      const wasConnected = isConnected;
      setIsConnected(state.isConnected);
      if (!wasConnected && state.isConnected) {
        // 重置source并添加时间戳,避免缓存导致不重新加载
        setVideoSource({ uri: `${question.video_url}?t=${Date.now()}` });
      }
    });

    return () => unsubscribe();
  }, [isConnected, question.video_url]);

  return (
    <Video
      videoStyle={{ marginHorizontal: 10 }}
      source={videoSource}
      rate={1.0}
      volume={1.0}
      isMuted={false}
      resizeMode={ResizeMode.CONTAIN}
      shouldPlay
      ref={videoRef}
      style={{ width: windowWidth, height: windowHeight }}
    />
  );
}

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 07:32:51