React Native Release构建中使用react-native-video-processing崩溃问题排查
Release构建下react-native-video-processing视频处理崩溃排查与解决
问题场景
从相册选择视频后,使用react-native-video-processing的ProcessingManager执行视频信息获取、压缩、裁剪操作,Debug构建运行正常,但仅在Release构建执行时应用崩溃。
核心代码
ProcessingManager.getVideoInfo('file://' + path).then(data => { const {size} = data; const {height, width} = size; const ratio = width / height; const options = { width: 720, height: 720, bitrateMultiplier: 3, minimumBitrate: 700000, }; ProcessingManager.compress('file://' + path, options) .then(data => { RNFetchBlob.fs.stat(data.source).then(stats => { const {path} = stats; ProcessingManager.trim(path, { startTime: 0, endTime: 60, }) .then(data => { navigation.navigate('AddVideo', { id: userId, items: [data], type: 'user', ratio, }); }); }); }); });
Release构建Logcat错误日志
Background concurrent copying GC freed 655389(26MB) AllocSpace objects, 88(9760KB) LOS objects, 49% free, 11MB/23MB, paused 95us,40us total 100.848ms 09-05 09:19:23.736 25101 25101 E com.x.x: Unknown bits set in runtime_flags: 0x40000000 09-05 09:19:23.736 25101 25101 I com.x.x: Using CollectorTypeCC GC. 09-05 09:19:23.740 25101 25101 E com.x.x: Not starting debugger since process cannot load the jdwp agent. 09-05 09:19:23.748 25101 25120 E com.x.x: Could not write anonymous vdex /system/framework/oat/arm64/mediatek-framework.vdex: Could not open /system/framework/oat/arm64/mediatek-framework.vdex for writing
崩溃原因分析
- 系统目录写入限制:Release构建下Android的SELinux策略严格禁止应用写入系统目录(如
/system/framework/oat/arm64/),日志中明确显示无法写入该路径,推测react-native-video-processing底层在Release模式下错误尝试将临时文件写入系统目录。 - 代码混淆破坏核心逻辑:ProGuard/R8在Release构建时可能混淆了
react-native-video-processing的原生类或方法,导致运行时找不到核心组件触发崩溃。 - 路径拼接不规范:直接拼接
'file://' + path可能导致重复前缀(若相册返回路径已带file://),引发文件访问异常,进而触发后续崩溃。
解决方案
1. 规范文件路径处理
避免重复拼接file://前缀:
const videoUri = path.startsWith('file://') ? path : `file://${path}`; ProcessingManager.getVideoInfo(videoUri).then(data => { // 后续所有ProcessingManager调用统一使用videoUri const {size} = data; const {height, width} = size; const ratio = width / height; const options = { width: 720, height: 720, bitrateMultiplier: 3, minimumBitrate: 700000, }; ProcessingManager.compress(videoUri, options) .then(data => { RNFetchBlob.fs.stat(data.source).then(stats => { const trimPath = stats.path.startsWith('file://') ? stats.path : `file://${stats.path}`; ProcessingManager.trim(trimPath, { startTime: 0, endTime: 60, }) .then(data => { navigation.navigate('AddVideo', { id: userId, items: [data], type: 'user', ratio, }); }); }); }); });
2. 添加ProGuard/R8保留规则
在android/app/proguard-rules.pro中添加规则,避免混淆库的核心原生代码:
-keep class com.shahenlibrary.** { *; } -keep class com.google.android.exoplayer.** { *; } -keep class com.google.android.exoplayer2.** { *; } -dontwarn com.shahenlibrary.** -dontwarn com.google.android.exoplayer.**
3. 指定应用私有存储作为输出目录
强制将压缩、裁剪后的视频保存到应用私有缓存目录,避免写入系统目录:
// 使用RNFetchBlob获取应用私有缓存目录 const outputDir = RNFetchBlob.fs.dirs.CacheDir; const options = { width: 720, height: 720, bitrateMultiplier: 3, minimumBitrate: 700000, outputPath: `${outputDir}/compressed_${Date.now()}.mp4` // 自定义唯一输出路径 }; ProcessingManager.compress(videoUri, options)
4. 优化Release构建配置
在android/app/build.gradle的Release构建块中关闭Debug相关配置:
buildTypes { release { debuggable false jniDebuggable false renderscriptDebuggable false minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } }
5. 确保权限配置正确
在AndroidManifest.xml中添加必要的文件访问权限,并在运行时动态申请(针对Android 10及以下):
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
内容的提问来源于stack exchange,提问作者Gourav Goel
相关产品推荐
相关产品推荐

