質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

解決済

1回答

2175閲覧

【Kotlin】ビデオファイルとオーディオファイルの結合方法について

tom_k_92

総合スコア7

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

0クリップ

投稿2021/12/05 07:36

AndroidでCameraXを使ったカメラアプリを開発中です。
CameraXで撮影したビデオファイル(mp4)を、オーディオファイル(.wav)と重ねてmp4ファイルとして保存したいと考えており、MediaCodec MediaMuxer を使用してそれぞれのファイルを処理する方法にたどり着きました。

参考URLを基に実装を進めているのですが、
E/MPEG4Writer: Stop() called but track is not started or stopped
というエラーが出ており、mp4ファイルも出力されない状態です。

ログを確認するとデータの処理は進んでいるので、エンコードではなくデコードの問題ではないかと考えております。
情報量が少ないため、どうすれば意図した処理を行えるのか分からないのですが、どなたかご教示いただけないでしょうか。

参考URL

android - How to mux audio file and video file?

コード

Kotlin

1 var outputFile = "" 2 try { 3 val file = File("生成するmp4ファイルのパス") 4 file.createNewFile() 5 outputFile = file.absolutePath 6 7 val videoExtractor = MediaExtractor() 8 videoExtractor.setDataSource("撮影したビデオファイルのパス") 9 10 val audioExtractor = MediaExtractor() 11 audioExtractor.setDataSource("オーディオファイルのパス") 12 13 val muxer = MediaMuxer(outputFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4) 14 15 videoExtractor.selectTrack(0) 16 val videoFormat = videoExtractor.getTrackFormat(0) 17 val videoTrack = muxer.addTrack(videoFormat) 18 19 audioExtractor.selectTrack(0) 20 val audioFormat = audioExtractor.getTrackFormat(0) 21 val audioTrack = muxer.addTrack(audioFormat) 22 23 var sawEOS = false 24 var frameCount = 0 25 val offset = 100 26 27 val sampleSize = 256 * 1024 28 val videoBuf: ByteBuffer = ByteBuffer.allocate(sampleSize) 29 val audioBuf: ByteBuffer = ByteBuffer.allocate(sampleSize) 30 val videoBufferInfo = MediaCodec.BufferInfo() 31 val audioBufferInfo = MediaCodec.BufferInfo() 32 33 videoExtractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC) 34 audioExtractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC) 35 36 muxer.start() 37 38 while (!sawEOS) { 39 videoBufferInfo.offset = offset 40 videoBufferInfo.size = videoExtractor.readSampleData(videoBuf, offset) 41 42 if (videoBufferInfo.size < 0 || audioBufferInfo.size < 0) { 43 Log.d("muxer", "saw input EOS.") 44 sawEOS = true 45 videoBufferInfo.size = 0 46 } else { 47 videoBufferInfo.presentationTimeUs = videoExtractor.sampleTime 48 videoBufferInfo.flags = videoExtractor.sampleFlags 49 muxer.writeSampleData(videoTrack, videoBuf, videoBufferInfo) 50 videoExtractor.advance() 51 52 frameCount++ 53 Log.d( 54 "muxer", 55 "Frame (" + frameCount + ") Video PresentationTimeUs:" + videoBufferInfo.presentationTimeUs + " Flags:" + videoBufferInfo.flags + " Size(KB) " + videoBufferInfo.size / 1024 56 ) 57 Log.d( 58 "muxer", 59 "Frame (" + frameCount + ") Audio PresentationTimeUs:" + audioBufferInfo.presentationTimeUs + " Flags:" + audioBufferInfo.flags + " Size(KB) " + audioBufferInfo.size / 1024 60 ) 61 } 62 } 63 Log.d("mux", "frame:$frameCount") 64 65 var sawEOS2 = false 66 var frameCount2 = 0 67 while (!sawEOS2) { 68 audioBufferInfo.offset = offset 69 audioBufferInfo.size = audioExtractor.readSampleData(audioBuf, offset) 70 71 if (videoBufferInfo.size < 0 || audioBufferInfo.size < 0) { 72 Log.d("muxer", "saw input EOS.") 73 sawEOS2 = true 74 audioBufferInfo.size = 0 75 } else { 76 audioBufferInfo.presentationTimeUs = audioExtractor.sampleTime 77 audioBufferInfo.flags = audioExtractor.sampleFlags 78 muxer.writeSampleData(audioTrack, audioBuf, audioBufferInfo) 79 audioExtractor.advance() 80 81 frameCount2++ 82 Log.d( 83 "muxer", 84 "Frame (" + frameCount2 + ") Video PresentationTimeUs:" + videoBufferInfo.presentationTimeUs + " Flags:" + videoBufferInfo.flags + " Size(KB) " + videoBufferInfo.size / 1024 85 ) 86 Log.d( 87 "muxer", 88 "Frame (" + frameCount2 + ") Audio PresentationTimeUs:" + audioBufferInfo.presentationTimeUs + " Flags:" + audioBufferInfo.flags + " Size(KB) " + audioBufferInfo.size / 1024 89 ) 90 } 91 } 92 Log.d("mux", "frame:$frameCount2") 93 94 muxer.stop() 95 muxer.release() 96 } catch (e: IOException) { 97 Log.d("muxer", "Mixer Error 1 " + e.message) 98 } catch (e: Exception) { 99 Log.d("muxer", "Mixer Error 2 " + e.message) 100 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

こちらの記事に従って実装し直したら、ビデオファイルとオーディオファイルが結合できました。
https://www.sisik.eu/blog/android/media/mix-audio-into-video

投稿2021/12/10 07:58

tom_k_92

総合スコア7

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問