我正在进行视频调整并使用k4l-video-trimmer库。我遇到了一个问题。我已下载最新代码并将其集成到Android Studio上。当我选择视频时,k4l-video-trimmer成功准备了视频,并正确显示视频信息和快照。我已将最大持续时间设置为10秒,但是当移动进度条以在特定持续时间裁剪视频时,在屏幕上显示的裁剪持续时间(01:21秒 - 01:31秒)持续10秒将变为(01 :21秒 - 01:36秒)变为15秒持续时间,这是一个问题,当我裁剪视频时,它将裁剪23秒。我不知道如何解决这个问题。请帮我解决这个问题
答案 0 :(得分:0)
您必须实现 MediaRecorder.OnInfoListener
以在 10 秒时手动停止录制。停止后,MediaRecorder
会返回到初始状态,并且必须再次进行设置才能重新开始录制。
public class VideoCapture extends Activity implements MediaRecorder.OnInfoListener {
public void startVideoRecording() {
// Normal MediaRecorder Setup
recorder.setMaxDuration(10000); // 10 seconds
recorder.setOnInfoListener(this); // very important
}
public void onInfo(MediaRecorder mrc, int mri, int extra) {
if (mri == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
Log.v("VIDEOCAPTURE","10 seconds");
mrc.stop();
}
}
}
现在,对于进度条,您可以使用 Timer
。
//fires once a second, decrease this to fire more frequently
private static final int TIMER_FREQ = 1000;
final ProgressBar progressBar = new ProgressBar(this); //where this is a Context
progressBar.setMax(10000);
Timer progressBarAdvancer = new Timer();
progressBarAdvancer.scheduleAtFixedRate(new TimerTask() {
public void run() {
progressBar.setProgress(progressBar.getProgress() + TIMER_FREQ);
}
},
0, //Delay before first execution
TIMER_FREQ);
这样做后,progressBar
会在独立于录制的线程上运行,但会在所需的 10 秒内完成。在这一点上,您可以停止录制并做其他事情。
此外,您还可以使用基于“k4l-video-trimmer”库的 Video Trimmer 来处理 k4l-video-trimmer 上的各种问题。
答案 1 :(得分:0)
您可以使用 mobile-ffmpeg 支持 API 级别 16+
fun scaleVideo(path: String, destinationFilePath: String) {
_loaderVisisble.value = true
viewModelScope.launch {
val cmd = arrayOf(
"-i",
path,
"-vf",
"scale=576:1024:force_original_aspect_ratio=decrease",
destinationFilePath
)
Log.v("str_Cmd", cmd.toString() + "")
val status = executeCommand(cmd)
when (status) {
FFmpeg.RETURN_CODE_SUCCESS -> {
_loaderVisisble.value = false
val mergedFile = File(destinationFilePath)
Log.v(
"target_file_size",
(mergedFile.length() / 1024).toString().toInt().toString() + ""
)
onVideoScaleListener.postValue(destinationFilePath)
}
FFmpeg.RETURN_CODE_CANCEL -> {
_loaderVisisble.value = false
}
else -> {
_loaderVisisble.value = false
}
}
}
}
private suspend fun executeCommand(cmd: Array<String>): Int {
var status = -1
withContext(Dispatchers.Default) {
val rc = FFmpeg.execute(cmd)
when (rc) {
FFmpeg.RETURN_CODE_SUCCESS -> {
Log.i(
Config.TAG,
"Command execution completed successfully."
)
}
FFmpeg.RETURN_CODE_CANCEL -> {
Log.i(
Config.TAG,
"Command execution cancelled by user."
)
}
else -> {
Log.i(
Config.TAG,
String.format(
"Command execution failed with rc=%d and the output below.",
rc
)
)
}
}
status = rc
}
return status
}