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

如何在React-Native中获取本地视频的FPS值?求最优解决方案

React-Native提取视频FPS值的最佳解决方案

方案一:使用Expo AV(适配Expo/裸RN项目)

Expo AV提供开箱即用的视频信息获取API,无需复杂配置,适合快速开发场景。

  • 安装依赖:
    npx expo install expo-av
    
  • 实现代码:
    import { AV } from 'expo-av';
    
    async function getVideoFPS(videoUri) {
      try {
        const videoInfo = await AV.getVideoInfoAsync(videoUri);
        return videoInfo.fps; // 直接返回视频帧率值
      } catch (error) {
        console.error('获取视频FPS失败:', error);
        return null;
      }
    }
    
  • 注意事项:裸RN项目需先执行npx expo prebuild完成Expo模块配置,确保视频URI为本地文件路径或合法网络地址。

方案二:使用react-native-ffmpeg(适配裸RN项目)

基于FFmpeg工具,支持几乎所有视频格式的帧率解析,兼容性极强。

  • 安装依赖:
    npm install react-native-ffmpeg
    # iOS需额外执行
    cd ios && pod install && cd ..
    
  • 实现代码:
    import RNFFmpeg from 'react-native-ffmpeg';
    
    async function getVideoFPS(videoPath) {
      // FFprobe命令:提取视频流的帧率信息
      const command = `-v error -select_streams v:0 -show_entries stream=r_frame_rate -of default=noprint_wrappers=1:nokey=1 ${videoPath}`;
      const result = await RNFFmpeg.execute(command);
      
      if (result.returnCode === 0) {
        // 解析帧率字符串(如30/1转为30.0)
        const [num, den] = result.output.trim().split('/');
        return parseFloat(num) / parseFloat(den);
      } else {
        console.error('解析帧率失败:', result);
        return null;
      }
    }
    
  • 注意事项:需申请文件读取权限(Android配置READ_EXTERNAL_STORAGE,iOS配置NSPhotoLibraryUsageDescription),视频路径需为本地绝对路径。

方案三:自定义原生模块(高度定制场景)

若上述库无法满足需求,可直接调用系统API获取帧率,性能最优。

iOS端(OC代码示例)

#import <AVFoundation/AVFoundation.h>
#import <React/RCTBridgeModule.h>

@interface VideoFPSModule : NSObject <RCTBridgeModule>
@end

@implementation VideoFPSModule

RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(getVideoFPS:(NSString *)videoPath resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
  NSURL *videoURL = [NSURL fileURLWithPath:videoPath];
  AVAsset *asset = [AVAsset assetWithURL:videoURL];
  AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] firstObject];
  
  if (videoTrack) {
    resolve(@(videoTrack.nominalFrameRate));
  } else {
    reject(@"NO_VIDEO_TRACK", @"未找到有效视频轨道", nil);
  }
}

@end

Android端(Java代码示例)

import android.media.MediaMetadataRetriever;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

public class VideoFPSModule extends ReactContextBaseJavaModule {
  public VideoFPSModule(ReactApplicationContext reactContext) {
    super(reactContext);
  }

  @Override
  public String getName() {
    return "VideoFPSModule";
  }

  @ReactMethod
  public void getVideoFPS(String videoPath, Promise promise) {
    MediaMetadataRetriever retriever = new MediaMetadataRetriever();
    try {
      retriever.setDataSource(videoPath);
      String fpsStr = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_CAPTURE_FRAMERATE);
      if (fpsStr != null) {
        promise.resolve(Float.parseFloat(fpsStr));
      } else {
        promise.reject("NO_FPS_DATA", "无法提取帧率信息");
      }
    } catch (Exception e) {
      promise.reject("ERROR", e.getMessage());
    } finally {
      retriever.release();
    }
  }
}

RN端调用

import { NativeModules } from 'react-native';
const { VideoFPSModule } = NativeModules;

async function getVideoFPS(videoPath) {
  try {
    return await VideoFPSModule.getVideoFPS(videoPath);
  } catch (error) {
    console.error('获取帧率失败:', error);
    return null;
  }
}

方案推荐

  • Expo项目优先选Expo AV,配置简单,API易用;
  • 裸RN项目且需兼容多格式视频,选react-native-ffmpeg;
  • 对性能要求极高或需定制化处理,选自定义原生模块。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 22:33:25