本文介紹了Mp4Parser音頻視頻合并輸出不能在所有設備上播放的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
在我的Android應用程序中,我正在分別下載Facebook視頻和音頻,并將其合并到一個輸出文件中。原因是Facebook視頻URL沒有聲音,而音頻URL是分開的。
我試過用這個mp4Parser來合并音頻和視頻,它在大多數(shù)設備上都工作得很好,但在Redmi/MI設備上播放設備文件時遇到了問題。
我遵循的步驟
下載MP4格式的無聲視頻。
下載M4a格式的音頻。
合并兩個文件并創(chuàng)建MP4格式的輸出文件。
合并完成后,沒有刪除任何聲音、視頻和臨時音頻。
下面是我的代碼
依賴關系
implementation 'com.iceteck.silicompressorr:silicompressor:2.2.4'
implementation('com.googlecode.mp4parser:isoparser:1.0.6') {
exclude group: 'org.aspectj', module: 'aspectjrt'
}
合并代碼
private fun mergeAudioAndVideo(
id: Int,
model: DatabaseDownloadItem?,
file: File?,
activityInstance: LocaleAwareCompatActivity?
) {
val mergingDetail = sharedPreferencesManager.getItemInMergingList(id)
if (mergingDetail != null) {
val timeInMillis = System.currentTimeMillis()
var list: ArrayList<DatabaseDownloadItem>? = sharedViewmodel.pendingMerge.value
if (list == null) {
list = arrayListOf()
}
list.add(model!!)
sharedViewmodel.pendingMerge.postValue(list)
sharedViewmodel.pendingMerge.value?.add(model!!)
CoroutineScope(Dispatchers.Main).launch {
var mergePendingItems: ArrayList<Int>? =
tinyDB?.getMergeList(AppConstants.MERGE_PENDING_DOWNLOADS)
if (mergePendingItems == null) {
mergePendingItems = arrayListOf()
}
if (!mergePendingItems.contains(model.id)) {
mergePendingItems.add(model.id)
}
tinyDB?.putMergeList(AppConstants.MERGE_PENDING_DOWNLOADS, mergePendingItems)
adapter.notifyDataSetChanged()
CoroutineScope(Dispatchers.IO + exceptionHandler).async {
val audiopath = mergingDetail.audioPath
val videopath = mergingDetail.videoPath
/*
following comment is kept for reference
val audiopath = "/storage/emulated/0/VideoDownloader/tempAudio_1643715180488.m4a"
val videopath = "/storage/emulated/0/VideoDownloader/1643715180480.mp4"*/
val output: String
val outputName = "output_${mergingDetail.originalFileName}"
mergingDetail.outputFileName = outputName
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val file = File(
getDownloaderFolderFromDownloads(),
"$outputName.mp4"
)
output = file.absolutePath
mergingDetail.outputFile = file
} else {
val file = File(
Environment.getExternalStorageDirectory()
.toString() + "/VideoDownloader/",
"$outputName.mp4"
)
output = file.absolutePath
mergingDetail.outputFile = file
}
var videoOutput: Movie? = null
var audioOutput: Movie? = null
kotlin.runCatching {
videoOutput = MovieCreator.build(videopath)
audioOutput = MovieCreator.build(audiopath)
}
val finalTrack: MutableList<Track> = ArrayList()
for (track in videoOutput?.tracks!!) {
if (track.handler.equals("vide")) finalTrack.add(track)
}
for (track in audioOutput?.tracks!!) {
if (track.handler.equals("soun")) finalTrack.add(track)
}
videoOutput?.tracks = finalTrack
val mp4file: Container = DefaultMp4Builder().build(videoOutput)
kotlin.runCatching {
val fc: FileChannel = FileOutputStream(File(output)).getChannel()
mp4file.writeContainer(fc)
fc.close()
}.onFailure { error ->
val abc = error
}.onSuccess { someFuncReturnValue ->
val abc = "dss"
}
}.await()
Toast.makeText(activityInstance, "Audio Video Merging Done", Toast.LENGTH_SHORT)
.show()
mergingDetail.isMergingDone = true
sharedPreferencesManager.updateItemInMergingList(id, mergingDetail)
executeDownloadCompletion(model, file, activityInstance)
deleteTempAudioFile(File(mergingDetail.audioPath!!), activityInstance)
deleteOldMutedVideo(File(mergingDetail.videoPath!!), activityInstance)
renameOutputFileWithDBName(mergingDetail, activityInstance)
var list: ArrayList<DatabaseDownloadItem>? = sharedViewmodel.pendingMerge.value
if (list != null && list!!.size > 0) {
list!!.remove(model!!)
sharedViewmodel.pendingMerge.postValue(list)
sharedViewmodel.pendingMerge.value?.add(model!!)
}
notificationWork(model, file, activityInstance)
sharedPreferencesManager.deleteItemInMergingList(id)
}
}
}
這在大多數(shù)設備中都工作得很好,但在MI設備(即Redmi S2,MUI版本MUI Global 12.0.2)中,我在播放輸出文件時遇到問題,文件已損壞,無法播放。顯示的錯誤只是標題未知。
請注意我還嘗試了以下依賴項組合,但這會在輸出文件中生成滯后,因此刪除了這兩個項。
implementation 'org.mp4parser:isoparser:1.9.41'
implementation 'org.mp4parser:muxer:1.9.41
誰能推薦一下mp4parser用于合并音頻文件和視頻文件的正確usgae和依賴項版本。
如有任何幫助,將不勝感激。
謝謝
推薦答案
使用FFmpeg庫,它將完成所有工作。您只需提供一個Facebook音頻和視頻鏈接和您的目錄的存儲路徑,您將通過文件API獲得。它將下載音頻和視頻,然后將它們合并。
這個簡單的命令將實現(xiàn)所有的魔力。
val cmd = "-i $videoUrl -i $audioUrl -c:v copy -c:a aac $storagePath"
FFmpeg.executeAsync(cmd, object: ExecuteCallback())
這篇關于Mp4Parser音頻視頻合并輸出不能在所有設備上播放的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,