microshow / RxFFmpeg

🔥💥RxFFmpeg 是基于 ( FFmpeg 4.0 + X264 + mp3lame + fdk-aac + opencore-amr + openssl ) 编译的适用于 Android 平台的音视频编辑、视频剪辑的快速处理框架,包含以下功能:视频拼接,转码,压缩,裁剪,片头片尾,分离音视频,变速,添加静态贴纸和gif动态贴纸,添加字幕,添加滤镜,添加背景音乐,加速减速视频,倒放音视频,音频裁剪,变声,混音,图片合成视频,视频解码图片,抖音首页,视频播放器及支持 OpenSSL https 等主流特色功能
4.46k stars 748 forks source link

视频压缩+封面获取 #96

Closed Khaos116 closed 4 years ago

Khaos116 commented 4 years ago

//封面获取命令 @Throws private fun getCommandFirstFrame( originPath: String, outPath: String ): Array { //读取图片尺寸和旋转角度 val mMetadataRetriever = MediaMetadataRetriever() mMetadataRetriever.setDataSource(originPath) val videoRotation = mMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION) val videoHeight = mMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT) val videoWidth = mMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH) mMetadataRetriever.release() val width: Int val height: Int if (Integer.parseInt(videoRotation) == 90 || Integer.parseInt(videoRotation) == 270) { //角度不对需要宽高调换 width = videoHeight.toInt() height = videoWidth.toInt() } else { width = videoWidth.toInt() height = videoHeight.toInt() } //return String.format("ffmpeg -y -i %1\$s -y -f image2 -t 0.001 -s %2\$sx%3\$s %4\$s",originPath, width, height, outPath) val list = mutableListOf() list.add("ffmpeg") list.add("-y") list.add("-i") list.add(originPath) list.add("-y") list.add("-f") list.add("image2") list.add("-t") list.add("0.001") list.add("-s") list.add("${width}x${height}") list.add(outPath) return list.toTypedArray()//采用list转换,防止文件名带空格造成分割错误 }

//文件压缩命令 private fun getCommandCompress( originPath: String, outPath: String ): Array? { //https://blog.csdn.net/qq_31332467/article/details/79166945 //4K视频可能会闪退,所以需要添加尺寸压缩 val mMetadataRetriever = MediaMetadataRetriever() mMetadataRetriever.setDataSource(originPath) val videoRotation = mMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION) val videoHeight = mMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT) val videoWidth = mMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH) val bitrate = mMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE) mMetadataRetriever.release() //码率低于400不进行压缩 if (bitrate.toInt() < 400 1000) return null val newBitrate = if (bitrate.toInt() > 3000 1000) { 3000 } else { (bitrate.toInt() * 0.8f / 1000f).toInt() } val width: Int val height: Int if (Integer.parseInt(videoRotation) == 90 || Integer.parseInt(videoRotation) == 270) { //角度不对需要宽高调换 width = videoHeight.toInt() height = videoWidth.toInt() } else { width = videoWidth.toInt() height = videoHeight.toInt() } //需要根据视频大小和视频时长计算得到需要压缩的码率,不然会导致高清视频压缩后变模糊,非高清视频压缩后文件变大 //https://blog.csdn.net/zhezhebie/article/details/79263492 val list = mutableListOf() list.add("ffmpeg") list.add("-y") list.add("-i") list.add(originPath) list.add("-b") list.add("${newBitrate}k") list.add("-r") list.add("30") list.add("-vcodec") list.add("libx264") if (min(width, height) > 1080) {//大于1080p list.add("-vf") list.add("scale=${if (width > height) "1080:-1" else "-1:1080"}") } list.add("-preset") list.add("superfast") list.add(outPath) return list.toTypedArray()//采用list转换,防止文件名带空格造成分割错误 }