diff --git a/app/build.gradle b/app/build.gradle index 0560342..1d6641c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -64,6 +64,7 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' implementation project(path: ':ffmpeg') // implementation 'com.cli.ffmpeg:command-android-lite:0.0.1' +// implementation 'com.github.AnJoiner:FFmpegCommand:1.2.0' implementation 'androidx.recyclerview:recyclerview:1.1.0' // 腾讯bugly implementation 'com.tencent.bugly:crashreport:3.3.1' diff --git a/ffmpeg-lite/.gitignore b/ffmpeg-lite/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/ffmpeg-lite/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/ffmpeg-lite/build.gradle b/ffmpeg-lite/build.gradle deleted file mode 100644 index b00c0f5..0000000 --- a/ffmpeg-lite/build.gradle +++ /dev/null @@ -1,46 +0,0 @@ -plugins { - id 'com.android.library' - id 'kotlin-android' -} - -android { - compileSdkVersion 30 - buildToolsVersion "30.0.3" - - defaultConfig { - minSdkVersion 15 - targetSdkVersion 30 - versionCode 1 - versionName "1.0" - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles "consumer-rules.pro" - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } -} - -dependencies { - - implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'androidx.core:core-ktx:1.3.2' - implementation 'androidx.appcompat:appcompat:1.2.0' - implementation 'com.google.android.material:material:1.3.0' - testImplementation 'junit:junit:4.+' - androidTestImplementation 'androidx.test.ext:junit:1.1.2' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' - - apply from: 'nexus.gradle' -} diff --git a/ffmpeg-lite/consumer-rules.pro b/ffmpeg-lite/consumer-rules.pro deleted file mode 100644 index e69de29..0000000 diff --git a/ffmpeg-lite/nexus.gradle b/ffmpeg-lite/nexus.gradle deleted file mode 100644 index 0c1341f..0000000 --- a/ffmpeg-lite/nexus.gradle +++ /dev/null @@ -1,40 +0,0 @@ -apply plugin: 'maven' - - -task androidJavadocs(type: Javadoc) { - source = android.sourceSets.main.java.srcDirs - classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) -} - -task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) { - classifier = 'javadoc' - from androidJavadocs.destinationDir -} - -task androidSourcesJar(type: Jar) { - classifier = 'sources' - from android.sourceSets.main.java.srcDirs -} - -artifacts { - archives androidSourcesJar -} - -Properties properties = new Properties() -properties.load(project.rootProject.file('local.properties').newDataInputStream()) - -uploadArchives { - configuration = configurations.archives - repositories{ - mavenDeployer { - repository(url: 'http://www.readdown.com:8081/repository/maven-releases/') { - authentication(userName: properties.getProperty("nexus.user"), password: properties.getProperty("nexus.password")) - } - pom.version = "0.0.1" - pom.artifactId = "command-android-lite" - pom.groupId = "com.cli.ffmpeg" - pom.name = "command-android-lite" - pom.packaging = 'aar' - } - } -} \ No newline at end of file diff --git a/ffmpeg-lite/proguard-rules.pro b/ffmpeg-lite/proguard-rules.pro deleted file mode 100644 index 481bb43..0000000 --- a/ffmpeg-lite/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/ffmpeg-lite/src/androidTest/java/com/coder/ffmpeg/ExampleInstrumentedTest.kt b/ffmpeg-lite/src/androidTest/java/com/coder/ffmpeg/ExampleInstrumentedTest.kt deleted file mode 100644 index 72a3630..0000000 --- a/ffmpeg-lite/src/androidTest/java/com/coder/ffmpeg/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.coder.ffmpeg - -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.ext.junit.runners.AndroidJUnit4 - -import org.junit.Test -import org.junit.runner.RunWith - -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("com.coder.ffmpeg.test", appContext.packageName) - } -} \ No newline at end of file diff --git a/ffmpeg-lite/src/main/AndroidManifest.xml b/ffmpeg-lite/src/main/AndroidManifest.xml deleted file mode 100644 index 052b42b..0000000 --- a/ffmpeg-lite/src/main/AndroidManifest.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/Attribute.kt b/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/Attribute.kt deleted file mode 100644 index 960e2b1..0000000 --- a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/Attribute.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.coder.ffmpeg.annotation - -import androidx.annotation.IntDef - -/** - * @author: AnJoiner - * @datetime: 20-4-8 - */ -@IntDef(Attribute.DURATION, Attribute.WIDTH, Attribute.HEIGHT, Attribute.VIDEO_BIT_RATE, Attribute.FPS, Attribute.CHANNELS, Attribute.SAMPLE_RATE, Attribute.AUDIO_BIT_RATE) -@Deprecated("") -annotation class Attribute { - companion object { - const val DURATION = 0 // 时长 - const val WIDTH = 1 //视频宽(分辨率px) - const val HEIGHT = 2 // 视频高(分辨率px) - const val VIDEO_BIT_RATE = 3 //视频比特率 - const val FPS = 4 //帧率 - const val CHANNELS = 5 //音频声道数 - const val SAMPLE_RATE = 6 //音频采样率 - const val AUDIO_BIT_RATE = 7 //音频比特率 - } -} \ No newline at end of file diff --git a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/CodecAttribute.kt b/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/CodecAttribute.kt deleted file mode 100644 index c01b918..0000000 --- a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/CodecAttribute.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.coder.ffmpeg.annotation - -import androidx.annotation.IntDef - -/** - * @author: AnJoiner - * @datetime: 20-9-9 - */ -@IntDef(CodecAttribute.ENCODE, - CodecAttribute.DECODE, - CodecAttribute.ENCODE_AUDIO, - CodecAttribute.DECODE_AUDIO, - CodecAttribute.ENCODE_VIDEO, - CodecAttribute.DECODE_VIDEO, - CodecAttribute.ENCODE_OTHER, - CodecAttribute.DECODE_OTHER) -annotation class CodecAttribute { - companion object { - const val ENCODE = 1 // 编码格式 - const val DECODE = 2 // 解码格式 - const val ENCODE_AUDIO = 3 // 音频编码格式 - const val DECODE_AUDIO = 4 // 音频解码格式 - const val ENCODE_VIDEO = 5 // 视频编码格式 - const val DECODE_VIDEO = 6 // 视频解码格式 - const val ENCODE_OTHER = 7 // 其他编码格式 - const val DECODE_OTHER = 8 // 其他解码格式 - } -} \ No newline at end of file diff --git a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/Direction.kt b/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/Direction.kt deleted file mode 100644 index 293d7cc..0000000 --- a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/Direction.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.coder.ffmpeg.annotation - -import androidx.annotation.IntDef - -/** - * @author: AnJoiner - * @datetime: 19-12-19 - */ -@IntDef(Direction.LAYOUT_HORIZONTAL, - Direction.LAYOUT_VERTICAL) -annotation class Direction { - companion object { - const val LAYOUT_HORIZONTAL = 1 - const val LAYOUT_VERTICAL = 2 - } -} \ No newline at end of file diff --git a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/FormatAttribute.kt b/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/FormatAttribute.kt deleted file mode 100644 index 3aa504d..0000000 --- a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/FormatAttribute.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.coder.ffmpeg.annotation - -import androidx.annotation.IntDef - -/** - * @author: AnJoiner - * @datetime: 20-9-9 - */ -@IntDef(FormatAttribute.INPUT_FORMAT, - FormatAttribute.OUTPUT_FORMAT) -annotation class FormatAttribute { - companion object { - const val INPUT_FORMAT = 1 // 输入格式 - const val OUTPUT_FORMAT = 2 // 输出格式 - } -} \ No newline at end of file diff --git a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/ImageFormat.kt b/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/ImageFormat.kt deleted file mode 100644 index e4d8034..0000000 --- a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/ImageFormat.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.coder.ffmpeg.annotation - -import androidx.annotation.StringDef - -/** - * @author: AnJoiner - * @datetime: 19-12-22 - */ -@StringDef(ImageFormat.PNG, - ImageFormat.JPG) -annotation class ImageFormat { - companion object { - const val PNG = "png" - const val JPG = "jpg" - } -} \ No newline at end of file diff --git a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/MediaAttribute.kt b/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/MediaAttribute.kt deleted file mode 100644 index cd36e0a..0000000 --- a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/MediaAttribute.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.coder.ffmpeg.annotation - -import androidx.annotation.IntDef -import com.coder.ffmpeg.annotation.MediaAttribute - -/** - * @author: AnJoiner - * @datetime: 20-11-22 - */ -@IntDef(MediaAttribute.DURATION, - MediaAttribute.WIDTH, - MediaAttribute.HEIGHT, - MediaAttribute.VIDEO_BIT_RATE, - MediaAttribute.FPS, - MediaAttribute.CHANNELS, - MediaAttribute.SAMPLE_RATE, - MediaAttribute.AUDIO_BIT_RATE) -annotation class MediaAttribute { - companion object { - const val DURATION = 0 // 时长 - const val WIDTH = 1 //视频宽(分辨率px) - const val HEIGHT = 2 // 视频高(分辨率px) - const val VIDEO_BIT_RATE = 3 //视频比特率 - const val FPS = 4 - const val CHANNELS = 5 //音频声道数 - const val SAMPLE_RATE = 6 //音频采样率 - const val AUDIO_BIT_RATE = 7 //音频比特率 - } -} \ No newline at end of file diff --git a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/Transpose.kt b/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/Transpose.kt deleted file mode 100644 index e25633f..0000000 --- a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/annotation/Transpose.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.coder.ffmpeg.annotation - -import androidx.annotation.IntDef - -/** - * @author: AnJoiner - * @datetime: 19-12-30 - */ -@IntDef(Transpose.CLOCKWISE_ROTATION_90, - Transpose.ANTICLOCKWISE_ROTATION_90, - Transpose.CLOCKWISE_ROTATION_90_FLIP, - Transpose.ANTICLOCKWISE_ROTATION_90_FLIP) -annotation class Transpose { - companion object { - //顺时针旋转画面90度 - const val CLOCKWISE_ROTATION_90 = 1 - - // 逆时针旋转画面90度 - const val ANTICLOCKWISE_ROTATION_90 = 2 - - //顺时针旋转画面90度再水平翻转 - const val CLOCKWISE_ROTATION_90_FLIP = 3 - - // 逆时针旋转画面90度水平翻转 - const val ANTICLOCKWISE_ROTATION_90_FLIP = 0 - } -} \ No newline at end of file diff --git a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/call/CommonCallBack.kt b/ffmpeg-lite/src/main/java/com/coder/ffmpeg/call/CommonCallBack.kt deleted file mode 100644 index 1cfb5f3..0000000 --- a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/call/CommonCallBack.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.coder.ffmpeg.call - -/** - * @author: AnJoiner - * @datetime: 19-12-17 - */ -open class CommonCallBack : IFFmpegCallBack { - override fun onStart() {} - override fun onProgress(progress: Int, pts: Long) {} - override fun onCancel() {} - override fun onComplete() {} - override fun onError(errorCode: Int, errorMsg: String?) {} -} \ No newline at end of file diff --git a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/call/IFFmpegCallBack.kt b/ffmpeg-lite/src/main/java/com/coder/ffmpeg/call/IFFmpegCallBack.kt deleted file mode 100644 index 64f502c..0000000 --- a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/call/IFFmpegCallBack.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.coder.ffmpeg.call - -interface IFFmpegCallBack { - /** - * 开始回调 - */ - fun onStart() - - /** - * 进度回调 - * - * @param progress 当前执行进度 - * @param pts 当前执行长度 - */ - fun onProgress(progress: Int, pts: Long) - - /** - * 取消回调 - */ - fun onCancel() - - /** - * 完成回调 - */ - fun onComplete() - - /** - * 错误回调 - * - * @param errorCode 错误码 - * @param errorMsg 错误内容 - */ - fun onError(errorCode: Int, errorMsg: String?) -} \ No newline at end of file diff --git a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/jni/FFmpegCmd.kt b/ffmpeg-lite/src/main/java/com/coder/ffmpeg/jni/FFmpegCmd.kt deleted file mode 100644 index fd0c0d1..0000000 --- a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/jni/FFmpegCmd.kt +++ /dev/null @@ -1,210 +0,0 @@ -package com.coder.ffmpeg.jni - -import com.coder.ffmpeg.annotation.CodecAttribute -import com.coder.ffmpeg.annotation.FormatAttribute -import com.coder.ffmpeg.annotation.MediaAttribute -import com.coder.ffmpeg.call.IFFmpegCallBack -import java.util.* - -/** - * @author: AnJoiner - * @datetime: 19-12-17 - */ -internal class FFmpegCmd private constructor() { - // Program execution callback - private val mCallBacks = Collections.synchronizedList(ArrayList()) - // debugging mode - private var ffdebug = true - - companion object { - var instance: FFmpegCmd? = null - get() { - if (field == null) { - field = FFmpegCmd() - } - return field - } - private set - - init { - System.loadLibrary("ffmpeg-org") - System.loadLibrary("ffmpeg-command") - } - } - - - /** - * Whether to enable debugging mode - * @param debug true or false - */ - external fun setDebug(debug: Boolean) - - /** - * Provide ffmpeg command method to execute - * @param command ffmeng command - * @return execute status - */ - fun runCmd(command: Array): Int { - return run(getCommand(command)) - } - - /** - * Provide ffmpeg command method to execute - * @param command ffmeng command - * @param callBack callback result - * @return execute status - */ - fun runCmd(command: Array, callBack: IFFmpegCallBack?): Int { - mCallBacks.add(callBack) - return run(getCommand(command)) - } - - /** - * Return the complete command - * @param cmd ffmeng command - * @return ffmeng command - */ - private fun getCommand(cmd: Array): String { - val stringBuffer = StringBuilder() - for (i in cmd.indices) { - stringBuffer.append(cmd[i]) - if (i < cmd.size - 1) { - stringBuffer.append(" ") - } - } - return stringBuffer.toString() - } - - /** - * Re-survive command according to whether it is debug mode - * @param cmd ffmeng command - * @return ffmeng command - */ - private fun buildCommand(cmd: Array): Array { - val cmds = arrayOfNulls(cmd.size + 1) - for (i in cmds.indices) { - when { - i < 1 -> { - cmds[i] = cmd[i] - } - i == 1 -> { - cmds[i] = "-d" - } - else -> { - cmds[i] = cmd[i - 1] - } - } - } - return if (ffdebug) cmds else cmd - } - - /** - * Execute ffmpeg command method - * @param command ffmeng command - * @return execute status - */ - private external fun run(command: String?): Int - - /** - * Get media information - * @param videoPath media path - * @param type information type - * @return media information - */ - fun getMediaInfo(videoPath: String?, @MediaAttribute type: Int): Int? { - return info(videoPath, type) - } - - /** - * Call native to get media information. - * @param videoPath media path - * @param type information type. - */ - private external fun info(videoPath: String?, type: Int): Int - - /** - * Provide method to get format info . - * @param format format type. - */ - fun getFormatInfo(@FormatAttribute format: Int): String { - return formatInfo(format) - } - - /** - * Call native to get support format. - * @param format format type. - * - */ - private external fun formatInfo(format: Int): String - - /** - * Provide method to get Codec info . - * @param codec codec type. - */ - fun getCodecInfo(@CodecAttribute codec: Int): String { - return codecInfo(codec) - } - /** - * Call native to get support codec. - * @param codec codec type. - * - */ - private external fun codecInfo(codec: Int): String - - @Deprecated("") - external fun exit() - - external fun cancel() - - /** - * Provide the callback of start execute commands. - */ - fun onStart() { - for (callBack in mCallBacks) { - callBack.onStart() - } - } - - /** - * Provide the callback of progress - * @param progress progress for ffmpeg - * @param pts duration of current ffmepg command execution - */ - fun onProgress(progress: Int, pts: Long) { - for (callBack in mCallBacks) { - callBack.onProgress(progress, pts) - } - } - - /** - * Provide the callback of cancel execute commands. - */ - fun onCancel() { - for (callBack in mCallBacks) { - callBack.onCancel() - mCallBacks.remove(callBack) - } - } - - /** - * Provide the callback of execute commands is completed. - */ - fun onComplete() { - for (callBack in mCallBacks) { - callBack.onComplete() - mCallBacks.remove(callBack) - } - } - - /** - * Provide the callback of error execute commands. - * @param errorCode error code of execute commands. - * @param errorMsg error message of execute commands. - */ - fun onError(errorCode: Int, errorMsg: String?) { - for (callBack in mCallBacks) { - callBack.onError(errorCode, errorMsg) - mCallBacks.remove(callBack) - } - } -} \ No newline at end of file diff --git a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/jni/FFmpegCommand.kt b/ffmpeg-lite/src/main/java/com/coder/ffmpeg/jni/FFmpegCommand.kt deleted file mode 100644 index 752515e..0000000 --- a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/jni/FFmpegCommand.kt +++ /dev/null @@ -1,84 +0,0 @@ -package com.coder.ffmpeg.jni - -import com.coder.ffmpeg.annotation.CodecAttribute -import com.coder.ffmpeg.annotation.FormatAttribute -import com.coder.ffmpeg.annotation.MediaAttribute -import com.coder.ffmpeg.call.IFFmpegCallBack - -/** - * @author: AnJoiner - * @datetime: 19-12-17 - */ -object FFmpegCommand { - /** - * Whether to enable debug mode - * - * @param debug true:enable false :not enable - */ - @JvmStatic - fun setDebug(debug: Boolean) { - FFmpegCmd.instance?.setDebug(debug) - } - - /** - * Get media information - * - * @param path media path - * @param type media attribute type [MediaAttribute] - * @return media information - */ - @JvmStatic - fun getMediaInfo(path: String?, @MediaAttribute type: Int): Int? { - return FFmpegCmd.instance?.getMediaInfo(path, type) - } - - /** - * Get support for unpacking format - * - * @param formatType format attribute type [FormatAttribute] - * @return format information - */ - @JvmStatic - fun getSupportFormat(@FormatAttribute formatType: Int): String? { - return FFmpegCmd.instance?.getFormatInfo(formatType) - } - - /** - * Get support codec - * - * @param codecType codec attribute type [CodecAttribute] - * @return codec info - */ - @JvmStatic - fun getSupportCodec(@CodecAttribute codecType: Int): String? { - return FFmpegCmd.instance?.getCodecInfo(codecType) - } - - /** - * Execute FFmpeg commands. - * - * @param cmd ffmpeg commands [com.coder.ffmpeg.utils.FFmpegUtils] - */ - @JvmStatic - fun runCmd(cmd: Array, callBack: IFFmpegCallBack?): Int? { - return FFmpegCmd.instance?.runCmd(cmd, callBack) - } - - /** - * Execute FFmpeg commands. - * - * @param cmd ffmpeg commands [com.coder.ffmpeg.utils.FFmpegUtils] - */ - @JvmStatic - fun runCmd(cmd: Array): Int? { - return FFmpegCmd.instance?.runCmd(cmd) - } - - /** - * Quit execute. - */ - @JvmStatic - fun cancel() { - FFmpegCmd.instance?.cancel() - } -} \ No newline at end of file diff --git a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/utils/FFmpegUtils.kt b/ffmpeg-lite/src/main/java/com/coder/ffmpeg/utils/FFmpegUtils.kt deleted file mode 100644 index 568ea10..0000000 --- a/ffmpeg-lite/src/main/java/com/coder/ffmpeg/utils/FFmpegUtils.kt +++ /dev/null @@ -1,917 +0,0 @@ -package com.coder.ffmpeg.utils - -import android.annotation.SuppressLint -import android.util.Log -import com.coder.ffmpeg.annotation.Direction -import com.coder.ffmpeg.annotation.ImageFormat -import com.coder.ffmpeg.annotation.Transpose -import java.util.* - -/** - * @author: AnJoiner - * @datetime: 19-12-17 - */ -object FFmpegUtils { - /** - * 使用ffmpeg命令行进行音频转码 - * - * @param srcFile 源文件 - * @param targetFile 目标文件(后缀指定转码格式) - * @return 转码后的文件 - */ - @JvmStatic - fun transformAudio(srcFile: String?, targetFile: String?): Array { - var command = "ffmpeg -y -i %s %s" - command = String.format(command, srcFile, targetFile) - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * 使用ffmpeg命令行进行音频剪切 - * - * @param srcFile 源文件 - * @param startTime 剪切的开始时间(单位为秒) - * @param duration 剪切时长(单位为秒) - * @param targetFile 目标文件 - * @return 剪切后的文件 - */ - @SuppressLint("DefaultLocale") - @JvmStatic - fun cutAudio(srcFile: String?, startTime: Int, duration: Int, - targetFile: String?): Array { - var command = "ffmpeg -y -i %s -vn -acodec copy -ss %d -t %d %s" - command = String.format(command, srcFile, startTime, duration, targetFile) - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * @param srcFile 源文件 - * @param startTime 剪切的开始时间(单位为秒) - * @param endTime 剪切的结束时间(单位为秒) - * @param targetFile 目标文件 - * @return 剪切后的文件 - */ - @JvmStatic - fun cutAudio(srcFile: String?, startTime: String?, endTime: String?, - targetFile: String?): Array { - val cmd = "ffmpeg -y -i %s -vn -acodec copy -ss %s -t %s %s" - val command = String.format(cmd, srcFile, startTime, endTime, targetFile) - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * 使用ffmpeg命令行进行音频合并 - * - * @param srcFile 源文件 - * @param appendFile 待追加的文件 - * @param targetFile 目标文件 - * @return 合并后的文件 - */ - @JvmStatic - fun concatAudio(srcFile: String?, appendFile: String?, targetFile: String?): Array { - //ffmpeg -y -i "concat:123.mp3|124.mp3" -acodec copy output.mp3 - //ffmpeg -i 1.mp3 -i 2.mp3 -filter_complex '[0:0] [1:0] concat=n=2:v=0:a=1 [a]' -map [a] new.mp3 - var command = "ffmpeg -y -i concat:%s|%s -acodec copy %s" - command = String.format(command, srcFile, appendFile, targetFile) - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * 使用ffmpeg命令行进行音频混合 - * - * @param srcFile 源文件 - * @param mixFile 待混合文件 - * @param targetFile 目标文件 - * @return 混合后的文件 - */ - @JvmStatic - fun mixAudio(srcFile: String?, mixFile: String?, targetFile: String?): Array { - //-filter_complex - // amix=inputs=2:duration=shortest output.wav - var command = "ffmpeg -y -i %s -i %s -filter_complex amix=inputs=2:duration=shortest %s" - command = String.format(command, srcFile, mixFile, targetFile) - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * @param audio 源文件 - * @param reduce 音量(单位dB) - * @param outPath 输出地址 - * @return 命令 - */ - @JvmStatic - fun changeVolume(audio: String?, reduce: Int, outPath: String?): Array { - val cmd = "ffmpeg -y -i %s -af volume=%sdB %s" - val command = String.format(cmd, audio, reduce, outPath) - Log.d("FFMEPG", command) - return command.split(" ").toTypedArray() - } - - /** - * @param audio 源文件 - * @param reduce 音量倍数 - * @param outPath 输出地址 - * @return 命令 - */ - @JvmStatic - fun changeVolume(audio: String?, reduce: Float, outPath: String?): Array { - val cmd = "ffmpeg -y -i %s -af volume=%s %s" - val command = String.format(cmd, audio, reduce, outPath) - Log.d("FFMEPG", command) - return command.split(" ").toTypedArray() - } - - /** - * 使用ffmpeg命令行进行音视频合成 - * - * @param videoFile 视频文件 - * @param audioFile 音频文件 - * @param duration 视频时长 - * @param muxFile 目标文件 - * @return 合成后的文件 - */ - @SuppressLint("DefaultLocale") - @JvmStatic - fun mixAudioVideo(videoFile: String?, audioFile: String?, duration: Int, - muxFile: String?): Array { - //-t:时长 如果忽略音视频时长,则把"-t %d"去掉 - var command = "ffmpeg -y -i %s -i %s -t %d %s" - command = String.format(command, videoFile, audioFile, duration, muxFile) - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * 使用ffmpeg命令行进行音视频合成 - * - * @param videoFile 视频文件 - * @param audioFile 音频文件 (aac 格式) - * @param muxFile 目标文件 - * @return 合成后的文件 - */ - @SuppressLint("DefaultLocale") - @JvmStatic - fun mixAudioVideo(videoFile: String?, audioFile: String?, - muxFile: String?): Array { - //-t:时长 如果忽略音视频时长,则把"-t %d"去掉 - var command = "ffmpeg -y -i %s -i %s -codec copy %s" - command = String.format(command, videoFile, audioFile, muxFile) - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * 使用ffmpeg命令行进行抽取音频 - * - * @param srcFile 原文件 - * @param targetFile 目标文件 - * @return 抽取后的音频文件 - */ - @JvmStatic - fun extractAudio(srcFile: String?, targetFile: String?): Array { - //-vn:video not - var command = "ffmpeg -y -i %s -acodec copy -vn %s" - command = String.format(command, srcFile, targetFile) - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * 使用ffmpeg命令行进行抽取视频 - * - * @param srcFile 原文件 - * @param targetFile 目标文件 - * @return 抽取后的视频文件 - */ - @JvmStatic - fun extractVideo(srcFile: String?, targetFile: String?): Array { - //-an audio not - var command = "ffmpeg -y -i %s -vcodec copy -an %s" - command = String.format(command, srcFile, targetFile) - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * 使用ffmpeg命令行进行视频转码 - * - * @param srcFile 源文件 - * @param targetFile 目标文件(后缀指定转码格式) - * @return 转码后的文件 - */ - @JvmStatic - fun transformVideo(srcFile: String?, targetFile: String?): Array { - //指定目标视频的帧率、码率、分辨率 -// String transformVideoCmd = "ffmpeg -i %s -r 25 -b 200 -s 1080x720 %s"; - var command = "ffmpeg -y -i %s -vcodec copy -acodec copy %s" - command = String.format(command, srcFile, targetFile) - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * 使用ffmpeg命令行进行视频剪切(不包含) - * - * @param srcFile 源文件 - * @param startTime 剪切的开始时间(单位为秒) - * @param duration 剪切时长(单位为秒) - * @param targetFile 目标文件 - * @return 剪切后的文件 - */ - @SuppressLint("DefaultLocale") - @JvmStatic - fun cutVideo(srcFile: String?, startTime: Int, duration: Int, - targetFile: String?): Array { - var command = "ffmpeg -y -i %s -ss %d -t %d -c copy %s" - command = String.format(command, srcFile, startTime, duration, targetFile) - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * 使用ffmpeg命令行进行视频剪切(包含关键帧) - * - * @param srcFile 源文件 - * @param startTime 剪切的开始时间(单位为秒) - * @param duration 剪切时长(单位为秒) - * @param targetFile 目标文件 - * @return 剪切后的文件 - */ - @SuppressLint("DefaultLocale") - @JvmStatic - fun cutVideo2(srcFile: String?, startTime: Int, duration: Int, - targetFile: String?): Array { - var command = "ffmpeg -y -ss %d -t %d -accurate_seek -i %s -codec copy " + - "-avoid_negative_ts 1 %s" - command = String.format(command, startTime, duration, srcFile, targetFile) - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * 使用ffmpeg命令行进行音频合并 - * - * @param inputFile 输入文件(.txt格式) - * @param targetFile 目标文件 - * @return 合并后的文件 - */ - @JvmStatic - fun concatVideo(inputFile: String?, targetFile: String?): Array { - // ffmpeg -f concat -i inputs.txt -c copy output.flv - var command = "ffmpeg -y -f concat -i %s -codec copy %s" - command = String.format(command, inputFile, targetFile) - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * 使用ffmpeg命令行进行视频截图 - * - * @param srcFile 源文件 - * @param size 图片尺寸大小 - * @param targetFile 目标文件 - * @return 截图后的文件 - */ - @JvmStatic - fun screenShot(srcFile: String?, size: String?, targetFile: String?): Array { - var command = "ffmpeg -y -i %s -f image2 -t 0.001 -s %s %s" - command = String.format(command, srcFile, size, targetFile) - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * 使用ffmpeg命令行进行视频截图 - * - * @param srcFile 源文件 - * @param targetFile 目标文件 - * @return 截图后的文件 - */ - @JvmStatic - fun screenShot(srcFile: String?, targetFile: String?): Array { - var command = "ffmpeg -y -i %s -f image2 -t 0.001 %s" - command = String.format(command, srcFile, targetFile) - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * @param inputFile 视频源文件 - * @param targetDir 图片生成目录 - * @param format 图片格式 - * @return 图片文件 - */ - @JvmStatic - fun video2Image(inputFile: String?, targetDir: String?, - @ImageFormat format: String): Array { - //ffmpeg -i ss.mp4 -r 1 -f image2 image-%3d.jpeg - var command = "ffmpeg -y -i %s -r 1 -f image2 %s" - command = String.format(Locale.CHINESE, command, inputFile, targetDir) - command = "$command/%3d.$format" - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * 视频抽帧转成图片 - * - * @param inputFile 输入文件 - * @param startTime 开始时间 - * @param duration 持续时间 - * @param frameRate 帧率 - * @param targetFile 输出文件 - * @param format 图片格式 - * @return 视频抽帧的命令行 - */ - @JvmStatic - fun video2Image(inputFile: String?, startTime: Int, duration: Int, - frameRate: Int, targetFile: String?, - @ImageFormat format: String): Array { - //-ss:开始时间,单位为秒 - //-t:持续时间,单位为秒 - //-r:帧率,每秒抽多少帧 - var command = "ffmpeg -y -i %s -ss %s -t %s -r %s %s" - command = String.format(Locale.CHINESE, command, inputFile, startTime, duration, - frameRate, targetFile) - command = "$command%3d.$format" - return command.split(" ").toTypedArray() - } - - /** - * 使用ffmpeg命令行给视频添加水印 - * - * @param srcFile 源文件 - * @param waterMark 水印文件路径 - * @param targetFile 目标文件 - * @return 添加水印后的文件 - */ - @JvmStatic - fun addWaterMark(srcFile: String?, waterMark: String?, targetFile: String?): Array { - var command = "ffmpeg -y -i %s -i %s -filter_complex overlay=40:40 %s" - command = String.format(command, srcFile, waterMark, targetFile) - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * 使用ffmpeg命令行进行视频转成Gif动图 - * - * @param srcFile 源文件 - * @param startTime 开始时间 - * @param duration 截取时长 - * @param targetFile 目标文件 - * @return Gif文件 - */ - @SuppressLint("DefaultLocale") - @JvmStatic - fun video2Gif(srcFile: String?, startTime: Int, duration: Int, - targetFile: String?): Array { - //String screenShotCmd = "ffmpeg -i %s -vframes %d -s 320x240 -f gif %s"; - var command = "ffmpeg -y -i %s -ss %d -t %d -f gif %s" - command = String.format(command, srcFile, startTime, duration, targetFile) - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * 使用ffmpeg命令行进行屏幕录制 - * - * @param size 视频尺寸大小 - * @param recordTime 录屏时间 - * @param targetFile 目标文件 - * @return 屏幕录制文件 - */ - @SuppressLint("DefaultLocale") - @JvmStatic - fun screenRecord(size: String?, recordTime: Int, targetFile: String?): Array { - //-vd x11:0,0 指录制所使用的偏移为 x=0 和 y=0 - //String screenRecordCmd = "ffmpeg -vcodec mpeg4 -b 1000 -r 10 -g 300 -vd x11:0,0 -s %s %s"; - var command = "ffmpeg -vcodec mpeg4 -b 1000 -r 10 -g 300 -vd x11:0,0 -s %s -t " + - "%d %s" - command = String.format(command, size, recordTime, targetFile) - Log.i("VideoHandleActivity", "screenRecordCmd=$command") - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * 使用ffmpeg命令行进行图片合成视频 - * - * @param srcFile 源文件 - * @param targetFile 目标文件 - * @return 合成的视频文件 - */ - @SuppressLint("DefaultLocale") - @JvmStatic - fun image2Video(srcFile: String?, targetFile: String?): Array { - //-f image2:代表使用image2格式,需要放在输入文件前面 - var command = "ffmpeg -y -f image2 -r 1 -i %simg#d.jpg -vcodec mpeg4 %s" - command = String.format(command, srcFile, targetFile) - command = command.replace("#", "%") - Log.i("VideoHandleActivity", "combineVideo=$command") - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - @JvmStatic - fun image2Video(srcDir: String?, @ImageFormat format: String?, - targetFile: String?): Array { - //-f image2:代表使用image2格式,需要放在输入文件前面 - // ffmpeg -f image2 -i image-%3d.jpeg images.mp4 - var command = "ffmpeg -y -f image2 -r 1 -i %s/#3d.%s -vcodec mpeg4 %s" - command = String.format(command, srcDir, format, targetFile) - command = command.replace("#", "%") - return command.split(" ") //以空格分割为字符串数组 - .toTypedArray() - } - - /** - * 音频解码 - * - * @param srcFile 源文件 - * @param targetFile 目标文件 - * @param sampleRate 采样率 - * @param channel 声道:单声道为1/立体声道为2 - * @return 音频解码的命令行 - */ - @JvmStatic - fun decodeAudio(srcFile: String?, targetFile: String?, sampleRate: Int, - channel: Int): Array { - var command = "ffmpeg -y -i %s -acodec pcm_s16le -ar %d -ac %d -f s16le %s" - command = String.format(command, srcFile, sampleRate, channel, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 音频编码 - * - * @param srcFile 源文件pcm裸流 - * @param targetFile 编码后目标文件 - * @param sampleRate 采样率 - * @param channel 声道:单声道为1/立体声道为2 - * @return 音频编码的命令行 - */ - @SuppressLint("DefaultLocale") - @JvmStatic - fun encodeAudio(srcFile: String?, targetFile: String?, sampleRate: Int, - channel: Int): Array { - var command = "ffmpeg -y -f s16le -ar %d -ac %d -acodec pcm_s16le -i %s %s" - command = String.format(command, sampleRate, channel, srcFile, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 多画面拼接视频 - * - * @param input1 输入文件1 - * @param input2 输入文件2 - * @param direction 视频布局方向 - * @param targetFile 画面拼接文件 - * @return 画面拼接的命令行 - */ - @JvmStatic - fun multiVideo(input1: String?, input2: String?, targetFile: String?, - @Direction direction: Int): Array { -// String multiVideo = "ffmpeg -i %s -i %s -i %s -i %s -filter_complex " + -// "\"[0:v]pad=iw*2:ih*2[a];[a][1:v]overlay=w[b];[b][2:v]overlay=0:h[c]; -// [c][3:v]overlay=w:h\" %s"; - var command = "ffmpeg -y -i %s -i %s -filter_complex hstack %s" //hstack:水平拼接,默认 - if (direction == Direction.LAYOUT_VERTICAL) { //vstack:垂直拼接 - command = command.replace("hstack", "vstack") - } - command = String.format(command, input1, input2, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 视频反序倒播 - * - * @param inputFile 输入文件 - * @param targetFile 反序文件 - * @return 视频反序的命令行 - */ - @JvmStatic - fun reverseVideo(inputFile: String?, targetFile: String?): Array { - var command = "ffmpeg -y -i %s -filter_complex [0:v]reverse[v] -map [v] %s" //单纯视频反序 - command = String.format(command, inputFile, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 视频反序倒播 - * - * @param inputFile 输入文件 - * @param targetFile 反序文件 - * @return 视频反序的命令行 - */ - @JvmStatic - fun reverseAudioVideo(inputFile: String?, targetFile: String?): Array { - var command = "ffmpeg -y -i %s -filter_complex [0:v]reverse[v];[0:a]reverse[a] -map [v] -map [a] %s" - command = String.format(command, inputFile, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 视频降噪 - * - * @param inputFile 输入文件 - * @param targetFile 输出文件 - * @return 视频降噪的命令行 - */ - @JvmStatic - fun denoiseVideo(inputFile: String?, targetFile: String?): Array { - var command = "ffmpeg -y -i %s -nr 500 %s" - command = String.format(command, inputFile, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 视频叠加成画中画 - * - * @param inputFile1 输入文件 - * @param inputFile2 输入文件 - * @param targetFile 输出文件 - * @param x 小视频起点x坐标 - * @param y 小视频起点y坐标 - * @return 视频画中画的命令行 - */ - @SuppressLint("DefaultLocale") - @JvmStatic - fun picInPicVideo(inputFile1: String?, inputFile2: String?, x: Int, y: Int, - targetFile: String?): Array { - var command = "ffmpeg -y -i %s -i %s -filter_complex overlay=%d:%d %s" - command = String.format(command, inputFile1, inputFile2, x, y, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 视频缩小一倍 - * @param srcFile 源文件 - * @param targetFile 输出文件 - * @return 视频缩小一倍 命令行 - */ - @JvmStatic - fun videoDoubleDown(srcFile: String?, targetFile: String?): Array { - var command = "ffmpeg -y -i %s -vf scale=iw/2:-1 %s" - command = String.format(command, srcFile, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 视频放大一倍 - * @param srcFile 源文件 - * @param targetFile 输出文件 - * @return 视频放大一倍命令行 - */ - @Deprecated("") - @JvmStatic - fun videoDouble(srcFile: String?, targetFile: String?): Array { - var command = "ffmpeg -y -i %s -vf scale=iw*2:-1 %s" - command = String.format(command, srcFile, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 视频放大一倍 - * @param srcFile 源文件 - * @param targetFile 输出文件 - * @return 视频放大一倍命令行 - */ - @JvmStatic - fun videoDoubleUp(srcFile: String?, targetFile: String?): Array { - var command = "ffmpeg -y -i %s -vf scale=iw*2:-1 %s" - command = String.format(command, srcFile, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 视频缩放 - * @param srcFile 源文件 - * @param targetFile 输出文件 - * @param width 缩放后宽度 - * @param height 缩放后高度 - * @return 视频缩放命令行 - */ - @JvmStatic - fun videoScale(srcFile: String?, targetFile: String?, width: Int, height: Int): Array { - return scale(srcFile, targetFile, width, height) - } - - /** - * 视频缩放 - * @param srcFile 源文件 - * @param targetFile 输出文件 - * @param width 缩放后宽度 - * @return 视频缩放命令行 - */ - @JvmStatic - fun videoScale(srcFile: String?, targetFile: String?, width: Int): Array { - return scale(srcFile, targetFile, width) - } - - /** - * 图片缩放 - * @param srcFile 源文件 - * @param targetFile 输出文件 - * @param width 缩放后宽度 - * @param height 缩放后高度 - * @return 视频缩放命令行 - */ - @JvmStatic - fun imageScale(srcFile: String?, targetFile: String?, width: Int, height: Int): Array { - return scale(srcFile, targetFile, width, height) - } - - /** - * 图片缩放 - * @param srcFile 源文件 - * @param targetFile 输出文件 - * @param width 缩放后宽度 - * @return 视频缩放命令行 - */ - @JvmStatic - fun imageScale(srcFile: String?, targetFile: String?, width: Int): Array { - return scale(srcFile, targetFile, width) - } - - /** - * 缩放 - * @param srcFile 源文件 - * @param targetFile 输出文件 - * @param width 缩放后宽度 - * @param height 缩放后高度 - * @return 缩放命令行 - */ - @JvmStatic - fun scale(srcFile: String?, targetFile: String?, width: Int, height: Int): Array { - var command = "ffmpeg -y -i %s -vf scale=%d:%d %s" - command = String.format(Locale.CHINA, command, srcFile, width, height, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 按宽度等比例缩放 - * @param srcFile 源文件 - * @param targetFile 输出文件 - * @param width 缩放后宽度 - * @return 缩放命令行 - */ - @JvmStatic - fun scale(srcFile: String?, targetFile: String?, width: Int): Array { - var command = "ffmpeg -y -i %s -vf scale=%d:-1 %s" - command = String.format(Locale.CHINA, command, srcFile, width, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 倍速播放 - * @param srcFile 源文件 - * @param targetFile 输出文件 - * @return 倍速播放命令行 - */ - @JvmStatic - fun videoSpeed2(srcFile: String?, targetFile: String?): Array { - var command = "ffmpeg -y -i %s -filter_complex [0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a] -map [v] -map [a] %s" - command = String.format(command, srcFile, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 解码成YUV原始数据 - * @param srcFile 源文件 - * @param targetFile 输出文件 - * @return 视频解码命令行 - */ - @JvmStatic - fun decode2YUV(srcFile: String?, targetFile: String?): Array { - var command = "ffmpeg -y -i %s -an -c:v rawvideo -pixel_format yuv420p %s" - command = String.format(command, srcFile, targetFile) - return command.split(" ").toTypedArray() - } - /** - * YUV 编码 H264 - * @param srcFile 源文件 - * @param targetFile 输出文件 - * @param width 输出文件宽 - * @param height 输出文件高 - * @return YUV 转 H264命令行 - */ - /** - * YUV 转 H264 - * @param srcFile 源文件 - * @param targetFile 输出文件 - * @return YUV 转 H264命令行 - */ - @JvmOverloads - @JvmStatic - fun yuv2H264(srcFile: String?, targetFile: String?, width: Int = 720, height: Int = 1280): Array { - var command = "ffmpeg -y -f rawvideo -pix_fmt yuv420p -s #wx#h -r 30 -i %s -c:v libx264 -f rawvideo %s" - command = String.format(Locale.CHINA, command, srcFile, targetFile) - command = command.replace("#wx#h", width.toString() + "x" + height) - return command.split(" ").toTypedArray() - } - /** - * 音频淡入 - * @param srcFile 源文件 - * @param targetFile 输出文件 - * @param start 开始位置(s) - * @param duration 持续时间(s) - * @return 音频淡入命令行 - */ - /** - * 音频前5s淡入 - * @param srcFile 源文件 - * @param targetFile 输出文件 - * @return 音频前5s淡入命令行 - */ - @JvmOverloads - @JvmStatic - fun audioFadeIn(srcFile: String?, targetFile: String?, start: Int = 0, duration: Int = 5): Array { - var command = "ffmpeg -y -i %s -filter_complex afade=t=in:ss=%d:d=%d %s" - command = String.format(Locale.CHINA, command, srcFile, start, duration, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 音频淡出 - * @param srcFile 音频源文件 - * @param targetFile 输出文件 - * @param start 开始位置(s) - * @param duration 持续时间(s) - * @return 音频淡出命令行 - */ - @JvmStatic - fun audioFadeOut(srcFile: String?, targetFile: String?, start: Int, duration: Int): Array { - var command = "ffmpeg -y -i %s -filter_complex afade=t=out:st=%d:d=%d %s" - command = String.format(Locale.CHINA, command, srcFile, start, duration, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 视频亮度 - * @param srcFile 源文件 - * @param targetFile 输出文件 - * @param bright 亮度(-1.0 ~ 1.0), 默认0 - * @return 视频亮度命令行 - */ - @JvmStatic - fun videoBright(srcFile: String?, targetFile: String?, bright: Float): Array { - var command = "ffmpeg -y -i %s -c:v libx264 -b:v 800k -c:a libfdk_aac -vf eq=brightness=%f -f mp4 %s" - command = String.format(Locale.CHINA, command, srcFile, bright, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 视频对比度 - * @param srcFile 源文件 - * @param targetFile 输出文件 - * @param contrast 对比度(-2.0 ~ 2.0), 默认1.0 - * @return - */ - @JvmStatic - fun videoContrast(srcFile: String?, targetFile: String?, contrast: Float): Array { - var command = "ffmpeg -y -i %s -c:v libx264 -b:v 800k -c:a libfdk_aac -vf eq=contrast=%f -f mp4 %s" - command = String.format(Locale.CHINA, command, srcFile, contrast, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 视频旋转 - * @param srcFile 源文件 - * @param targetFile 输出文件 - * @param transpose - * @return 视频旋转命令行 - */ - @JvmStatic - fun videoRotation(srcFile: String?, targetFile: String?, @Transpose transpose: Int): Array { - var command = "ffmpeg -y -i %s -vf transpose=%d -b:v 600k %s" - command = String.format(Locale.CHINA, command, srcFile, transpose, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 从视频中获取一帧输出图片 - * @param srcFile 源文件 - * @param targetFile 目标文件(png 或 jpg) - * @param time 一帧的时间:hh:mm:ss.xxx - * @return 从视频中获取一帧输出图片命令行 - */ - @JvmStatic - fun frame2Image(srcFile: String?, targetFile: String?, time: String?): Array { - var command = "ffmpeg -y -i %s -ss %s -vframes 1 %s" - command = String.format(command, srcFile, time, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 将音频进行fdk_aac编码 - * @param srcFile 音频源文件 - * @param targetFile 音频输出文件(m4a或aac) - * @return 将音频进行fdk_aac编码命令 - */ - @JvmStatic - fun audio2Fdkaac(srcFile: String?, targetFile: String?): Array { - var command = "ffmpeg -y -i %s -c:a libfdk_aac %s" - command = String.format(command, srcFile, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 将音频进行VBR MP3编码 - * @param srcFile 音频源文件 - * @param targetFile 音频输出文件(mp3) - * @return 将音频进行VBR MP3编码命令 - */ - @JvmStatic - fun audio2Mp3lame(srcFile: String?, targetFile: String?): Array { - var command = "ffmpeg -y -i %s -c:a libmp3lame %s" - command = String.format(command, srcFile, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 将格式视频进行切片,形成m3u8的视频流(m3u8格式一般用于直播或者点播) - * @param srcFile 视频路径 - * @param targetFile 目标路径(以xxx.m3u8为输出) - * @param splitTime 切割时间 (单位:秒) - * @return 返回以target文件名开头的ts系列文件 如:out0.ts out1.ts ... - * - * [com.coder.ffmpeg.utils.FFmpegUtils.video2HLS] - */ - @Deprecated("") - @JvmStatic - fun videoHLS(srcFile: String?, targetFile: String?, splitTime: Int): Array { - var command = "ffmpeg -y -i %s -c copy -bsf:v h264_mp4toannexb -hls_time %s %s" - command = String.format(command, srcFile, splitTime, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 将格式视频进行切片,形成m3u8的视频流(m3u8格式一般用于直播或者点播) - * @param srcFile 视频路径 - * @param targetFile 目标路径(以xxx.m3u8为输出) - * @param splitTime 切割时间 (单位:秒) - * @return 返回以target文件名开头的ts系列文件 如:out0.ts out1.ts ... - */ - @JvmStatic - fun video2HLS(srcFile: String?, targetFile: String?, splitTime: Int): Array { - var command = "ffmpeg -y -i %s -c copy -bsf:v h264_mp4toannexb -hls_time %s %s" - command = String.format(command, srcFile, splitTime, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 将ts视频流合成视频 - * @param m3u8Index xx.m3u8视频索引 - * @param targetFile 目标路径 - * @return 返回合成视频 - */ - @JvmStatic - fun hls2Video(m3u8Index: String?, targetFile: String?): Array { - var command = "ffmpeg -y -i %s -c copy %s" - command = String.format(command, m3u8Index, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 将音频转为amr格式 - * @param srcFile 音频源文件 - * @param targetFile 目标文件 - * @return amr格式音频 - */ - @JvmStatic - fun audio2Amr(srcFile: String?, targetFile: String?): Array { - var command = "ffmpeg -y -i %s -c:a libopencore_amrnb -ar 8000 -ac 1 %s" - command = String.format(command, srcFile, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 生成静音音频 - * @param targetFile 目标文件 - * @return 静音音频 - */ - @JvmStatic - fun makeMuteAudio(targetFile: String?): Array { - var command = "ffmpeg -y -f lavfi -t 10 -i anullsrc %s" - command = String.format(command, targetFile) - return command.split(" ").toTypedArray() - } - - /** - * 使用ffmpeg进行推流 - * @param src 源文件 - * @param url 推流地址 - */ - @JvmStatic - fun rtmp(src: String?, url:String?):Array{ - var command = "ffmpeg -re -i %s -f flv %s" - command = String.format(command, src,url) - return command.split(" ").toTypedArray() - } -} \ No newline at end of file diff --git a/ffmpeg-lite/src/main/jniLibs/arm64-v8a/libffmpeg-command.so b/ffmpeg-lite/src/main/jniLibs/arm64-v8a/libffmpeg-command.so deleted file mode 100755 index fa90f37..0000000 Binary files a/ffmpeg-lite/src/main/jniLibs/arm64-v8a/libffmpeg-command.so and /dev/null differ diff --git a/ffmpeg-lite/src/main/jniLibs/arm64-v8a/libffmpeg-org.so b/ffmpeg-lite/src/main/jniLibs/arm64-v8a/libffmpeg-org.so deleted file mode 100755 index 3850951..0000000 Binary files a/ffmpeg-lite/src/main/jniLibs/arm64-v8a/libffmpeg-org.so and /dev/null differ diff --git a/ffmpeg-lite/src/main/jniLibs/armeabi-v7a/libffmpeg-command.so b/ffmpeg-lite/src/main/jniLibs/armeabi-v7a/libffmpeg-command.so deleted file mode 100755 index f55eb87..0000000 Binary files a/ffmpeg-lite/src/main/jniLibs/armeabi-v7a/libffmpeg-command.so and /dev/null differ diff --git a/ffmpeg-lite/src/main/jniLibs/armeabi-v7a/libffmpeg-org.so b/ffmpeg-lite/src/main/jniLibs/armeabi-v7a/libffmpeg-org.so deleted file mode 100755 index 9904ecc..0000000 Binary files a/ffmpeg-lite/src/main/jniLibs/armeabi-v7a/libffmpeg-org.so and /dev/null differ diff --git a/ffmpeg-lite/src/test/java/com/coder/ffmpeg/ExampleUnitTest.kt b/ffmpeg-lite/src/test/java/com/coder/ffmpeg/ExampleUnitTest.kt deleted file mode 100644 index f510899..0000000 --- a/ffmpeg-lite/src/test/java/com/coder/ffmpeg/ExampleUnitTest.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.coder.ffmpeg - -import org.junit.Test - -import org.junit.Assert.* - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} \ No newline at end of file