如何在React Native中

时间:2018-03-01 12:02:13

标签: javascript video react-native compression video-compression

尝试使用Shahen的反应原生视频处理:

以下是代码:

compressVideo(source) {
    const options = {
        width: 800,
        height: 800,
        bitrateMultiplier: 3,
        saveToCameraRoll: true, 
        saveWithCurrentDate: true, 
        removeAudio: true 
    };

    ProcessingManager.compress(source, options)
        .then(data => {
            console.log(data);
            this.setState({ base64String: data });
        })
        .catch(console.warn);
}

但它在Android设备中出错。

  

{[错误:压缩错误:失败。 ffmpeg版本3.3.5版权所有(c)   2000-2017 FFmpeg开发人员使用gcc 4.8(GCC)构建   配置: - target-os = linux   --cross前缀= /用户/克莎/项目/ ffmpeg的-机器人/工具链-机器人/ bin中/臂-Linux的androideabi-   --arch = arm --cpu = cortex-a8 --enable-runtime-cpudetect --sysroot = / Users / kesha / Projects / ffmpeg-android / toolchain-android / sysroot   --enable-libx264 --enable-pthreads --disable-debug --disable-ffserver --enable-version3 --enable-hardcoded-tables --disable -ffplay --disable-ffprobe --enable-yasm --disable -doc --disable-shared --enable-static --enable-nonfree --disable-network --enable-gpl --enable -ffmpeg --enable-small --disable-filters --enable-filter = copy - -enable-filter = trim --enable-filter = crop --enable-filter = scale --enable-filter = format --pkg-config = / Users / kesha / Projects / ffmpeg-android / ffmpeg-3.3-pkg- config --prefix = / Users / kesha / Projects / ffmpeg-android / build / armeabi-v7a --extra-cflags =' -I / Users / kesha / Projects / ffmpeg-android / toolchain-android / include   -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE = 2 -fno-strict-overflow -fstack-protector-all' --extra-ldflags =' -L / Users / kesha / Projects / ffmpeg-android / toolchain-android / lib -Wl,-z,relro -Wl,-z,now -pie' --extra-cxxflags = --extra-libs =' -lx264 -lm' libavutil 55. 58.100 / 55. 58.100 libavcodec 57. 89.100 / 57. 89.100 libavformat 57. 71.100 / 57. 71.100 libavdevice 57. 6.100 / 57. 6.100 libavfilter 6. 82.100 /   6. 82.100 libswscale 4. 6.100 / 4. 6.100 libswresample 2.7.100 / 2. 7.100 libpostproc 54. 5.100 / 54. 5.100Input#0,mov,mp4,m4a,3gp,3g2,mj2,from   '文件:///storage/emulated/0/DCIM/Camera/20180301_141708.mp4' ;:   元数据:major_brand:mp42 minor_version:0
  compatible_brands:isommp42 creation_time:   2018-03-01T08:47:13.000000Z com.android.version:7.0持续时间:   00:00:04.07,开始:0.000000,比特率:3366 kb / s流#0:0(eng):   视频:h264(avc1 / 0x31637661),yuv420p(电视,   smpte170m / smpte170m / bt709),640x480,3091 kb / s,SAR 1:1 DAR 4:3,29.88   fps,30 tbr,90k tbn,180k tbc(默认)元数据:旋转
  :90 creation_time:2018-03-01T08:47:13.000000Z
  handler_name:VideoHandle边数据:displaymatrix:   旋转-90.00度流#0:1(eng):音频:aac(mp4a /   0x6134706D),48000 Hz,立体声,fltp,256 kb / s(默认值)元数据:
  creation_time:2018-03-01T08:47:13.000000Z handler_name:   SoundHandleStream映射:流#0:0-> #0:0(h264(原生) - > h264   (libx264))按[q]停止,按[?]进行helpError重新初始化   过滤器!无法将帧注入过滤网络:内存不足错误   处理流#0的解码数据时:0转换失败!]   framesToPop:1,代码:' EUNSPECIFIED' } 03-01 15:40:05.658 29497 29772   I ReactNativeJS:4,{height:640,width:480} 03-01 15:40:05.757   29497 29772 W ReactNativeJS:{[错误:压缩错误:失败。 ffmpeg的   版本3.3.5版权所有(c)2000-2017 FFmpeg开发人员构建   用gcc 4.8(GCC)配置: - target-os = linux   --cross前缀= /用户/克莎/项目/ ffmpeg的-机器人/工具链-机器人/ bin中/臂-Linux的androideabi-   --arch = arm --cpu = cortex-a8 --enable-runtime-cpudetect --sysroot = / Users / kesha / Projects / ffmpeg-android / toolchain-android / sysroot   --enable-libx264 --enable-pthreads --disable-debug --disable-ffserver --enable-version3 --enable-hardcoded-tables --disable -ffplay --disable-ffprobe --enable-yasm --disable -doc --disable-shared --enable-static --enable-nonfree --disable-network --enable-gpl --enable -ffmpeg --enable-small --disable-filters --enable-filter = copy - -enable-filter = trim --enable-filter = crop --enable-filter = scale --enable-filter = format --pkg-config = / Users / kesha / Projects / ffmpeg-android / ffmpeg-3.3-pkg- config --prefix = / Users / kesha / Projects / ffmpeg-android / build / armeabi-v7a --extra-cflags =' -I / Users / kesha / Projects / ffmpeg-android / toolchain-android / include   -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE = 2 -fno-strict-overflow -fstack-protector-all' --extra-ldflags =' -L / Users / kesha / Projects / ffmpeg-android / toolchain-android / lib -Wl,-z,relro -Wl,-z,now -pie' --extra-cxxflags = --extra-libs =' -lx264 -lm' libavutil 55. 58.100 / 55. 58.100 libavcodec 57. 89.100 / 57. 89.100 libavformat 57. 71.100 / 57. 71.100 libavdevice 57. 6.100 / 57. 6.100 libavfilter 6. 82.100 /   6. 82.100 libswscale 4. 6.100 / 4. 6.100 libswresample 2.7.100 / 2. 7.100 libpostproc 54. 5.100 / 54. 5.100Input#0,mov,mp4,m4a,3gp,3g2,mj2,from   '文件:///storage/emulated/0/DCIM/Camera/20180301_141708.mp4' ;:   元数据:major_brand:mp42 minor_version:0
  compatible_brands:isommp42 creation_time:   2018-03-01T08:47:13.000000Z com.android.version:7.0持续时间:   00:00:04.07,开始:0.000000,比特率:3366 kb / s流#0:0(eng):   视频:h264(avc1 / 0x31637661),yuv420p(电视,   smpte170m / smpte170m / bt709),640x480,3091 kb / s,SAR 1:1 DAR 4:3,29.88   fps,30 tbr,90k tbn,180k tbc(默认)元数据:旋转
  :90 creation_time:2018-03-01T08:47:13.000000Z
  handler_name:VideoHandle边数据:displaymatrix:   旋转-90.00度流#0:1(eng):音频:aac(mp4a /   0x6134706D),48000 Hz,立体声,fltp,256 kb / s(默认值)元数据:
  creation_time:2018-03-01T08:47:13.000000Z handler_name:   SoundHandleStream映射:流#0:0-> #0:0(h264(原生) - > h264   (libx264))按[q]停止,按[?]进行helpError重新初始化   过滤器!无法将帧注入过滤网络:内存不足错误   处理流#0的解码数据时:0转换失败!]   framesToPop:1,代码:' EUNSPECIFIED' }

此问题的任何解决方案或在上传前压缩视频的任何其他方法。

2 个答案:

答案 0 :(得分:1)

使用rn-fetch-blob for android先转换路径,因为你得到的URI在android的情况下是临时的,在目录中找不到,

const res = await RNFetchBlob.fs.stat(SOURCE_URI);
src = "file://" + res.path;

ProcessingManager.compress(src, options)
    .then(data => {
        console.log(data);
        this.setState({ base64String: data });
    })
    .catch(console.warn);

这将解决路径问题。

答案 1 :(得分:1)

试试下面的代码,在 react-native 中成功压缩视频。它将 81MB 压缩成近 43MB。

import { Platform } from 'react-native';
import {RNFFmpeg} from "react-native-ffmpeg"
import RNFS from 'react-native-fs';

function processVideo(videoUrl, callback) {
  const finalVideo = `${RNFS.CachesDirectoryPath}/audioVideoFinal.mp4`;

  cacheResourcePath(videoUrl).then((rVideoUrl) => {
   const str_cmd = `-y -i ${rVideoUrl} -vcodec mpeg4 -acodec aac -qscale:v 3 -q:a 4 ${finalVideo}`;
   
    RNFFmpeg.execute(
      str_cmd,
    ).then((result) => {
      if (result === 0) {
        RNFS.unlink(rVideoUrl);

        callback({
          videoPath:
            Platform.OS === 'android' ? 'file://' + finalVideo : finalVideo,
        });
      }
    });
  });
};

async function cacheResourcePath(sourcePath) {
  const uriComponents = sourcePath.split('/');
  const fileNameAndExtension = uriComponents[uriComponents.length - 1].replaceAll(' ','');

  const destPath = `${RNFS.CachesDirectoryPath}/${fileNameAndExtension}`;

  await RNFS.copyFile(sourcePath, destPath);
  return destPath;
}