在我的应用程序中,我录制了一个视频,我想将我公司的网址覆盖在该视频的右下角。我用 MediaRecorder 录制视频,录制没有问题,但在视频中添加文本我没有成功。我搜索并找到了一些像 FFmpeg 和 JavaCV 这样的库,它们允许用户在视频上覆盖文本,但我不知道是否有任何方法可以在 Android 中使用它们。之后发现 OnPreviewFrame 返回相机预览的每一帧。我想在用户触摸录制按钮后获取所有帧,并使用画布在每个帧上绘制文本,然后将所有这些帧保存在一起,直到录制视频停止,并且视频持续时间固定为 15 秒。这是一个好的解决方案吗?如果是,我应该如何实现OnPreviewFrame函数?我知道如何绘制画布,但不知道如何将 data[] 转换为位图。
使用该方法对性能的影响非常大。 我绝对建议您深入研究 ffmeg。我相信它并不难使用,并且有简单的 ffmeg 库,无需使用 NDK。看一下这个库并检查是否有您需要的功能。
ffmpeg -i movie.mp4 -i logo.png -filter_complex overlay output.mp4
这个命令就是您正在寻找的东西。
如果您仍然想使用 ffmeg 以外的其他东西,我建议您看一下 MediaMetadataRetriever
public Bitmap getFrameAtTime (long timeUs)
这个方法是你可以使用的。它为您提供了可以绘制的位图。但它仍然会慢得要命。我尝试使用这种方法创建 gif,一段时间后又回到 ffmeg。
希望有帮助。
这是一个相当老的问题,但现在(2024 年)我们有 Media3 API 可以在视频上添加文本(而不是在实时摄像机录制中)。
这是预览更改的代码。
val mediaItem = MediaItem.Builder()
.setUri(videoUri)
.build()
val textEffect = TextOverlay.createStaticTextOverlay(
SpannableString(text),
)
val player = ExoPlayer.Builder(context)
.build()
.also { exoPlayer ->
exoPlayer.setMediaItem(mediaItem)
exoPlayer.setVideoEffects(listOf(OverlayEffect(ImmutableList.of(textEffect))))
exoPlayer.prepare()
}
这是将视频导出到文件的代码。
val mediaItem = MediaItem.Builder()
.setUri(videoUri.value)
.build()
val textEffect = TextOverlay.createStaticTextOverlay(
SpannableString(text.value),
)
val effects = Effects(
listOf(),
listOf(OverlayEffect(ImmutableList.of(textEffect))),
)
val editedMediaItem = EditedMediaItem.Builder(mediaItem)
.setEffects(effects)
.build()
val outputFile = File(context.filesDir, "test.mp4")
transformer.start(editedMediaItem, outputFile.absolutePath)
transformer.addListener(object : Transformer.Listener {
override fun onCompleted(composition: Composition, exportResult: ExportResult) {
onCompleted()
}
override fun onError(
composition: Composition,
exportResult: ExportResult,
exportException: ExportException
) {
onError(exportException)
}
})
您可以阅读我的博文了解更多详细信息:https://acomputerengineer.com/2024/09/23/add-text-on-video-in-android-using-media3-and-transformer-apis/