简体   繁体   English

为什么根据播放音频设备播放不同的声音? (在 Android 上将音频混合到视频中)

[英]Why do different sounds play depending on the playback audio device? (Mixing audio into video on Android)

I have a m4a music file and a mp4 video file.我有一个 m4a 音乐文件和一个 mp4 视频文件。 I want to mux music file and video file in to a mp4 file and save it.我想将音乐文件和视频文件混合到一个 mp4 文件中并保存。

Using this article as a reference, I made my own code.使用这篇文章作为参考,我编写了自己的代码。 My code almost works fine but different sounds play depending on the playback device .我的代码几乎可以正常工作,但会根据播放设备播放不同的声音

Android (Pixel 3a): Music + Video(without Audio) Android (Pixel 3a):音乐+视频(无音频)

iOS (Mac QuickTime Player, iPhone 11Pro): Music + Video(with Audio) ← I want to do this! iOS (Mac QuickTime Player,iPhone 11Pro):音乐+视频(带音频)←我想做这个!

Is there any solution??有什么解决办法吗??

my code:我的代码:

    fun mux(audioFile: String, videoFile: String, outFile: String) {

        // video
        val videoExtractor = MediaExtractor()
        videoExtractor.setDataSource(videoFile)
        videoExtractor.selectTrack(0)
        val videoFormat = videoExtractor.getTrackFormat(0)

        // audio
        val soundExtractor = MediaExtractor()
        soundExtractor.setDataSource(videoFile)
        soundExtractor.selectTrack(1)
        val soundFormat = soundExtractor.getTrackFormat(1)

        // music
        val audioExtractor = MediaExtractor()
        audioExtractor.setDataSource(audioFile)
        audioExtractor.selectTrack(0)
        val audioFormat = audioExtractor.getTrackFormat(0)

        val muxer: MediaMuxer

        val videoMetaData = MediaMetadataRetriever()
        videoMetaData.setDataSource(videoFile)
        val degreeString = videoMetaData.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION)
        val videoDegree = degreeString?.toInt() ?: 0
        muxer = MediaMuxer(outFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
        muxer.setOrientationHint(videoDegree)

        val videoIndex = muxer.addTrack(videoFormat)
        val soundIndex = muxer.addTrack(soundFormat)
        val audioIndex = muxer.addTrack(audioFormat)
        muxer.start()

        val maxChunkSize = 1024 * 1024
        val buffer = ByteBuffer.allocate(maxChunkSize)
        val videoBufferInfo = MediaCodec.BufferInfo()
        val soundBufferInfo = MediaCodec.BufferInfo()
        val audioBufferInfo = MediaCodec.BufferInfo()

        // copy video
        while (true) {
            val chunkSize = videoExtractor.readSampleData(buffer, 0)

            if (chunkSize > 0) {
                videoBufferInfo.presentationTimeUs = videoExtractor.sampleTime
                videoBufferInfo.flags = videoExtractor.sampleFlags
                videoBufferInfo.size = chunkSize

                muxer.writeSampleData(videoIndex, buffer, videoBufferInfo)

                videoExtractor.advance()
            } else {
                break
            }
        }

        // copy audio
        while (true) {
            val chunkSize = soundExtractor.readSampleData(buffer, 0)

            if (chunkSize > 0) {
                soundBufferInfo.presentationTimeUs = soundExtractor.sampleTime
                soundBufferInfo.flags = soundExtractor.sampleFlags
                soundBufferInfo.size = chunkSize

                muxer.writeSampleData(soundIndex, buffer, soundBufferInfo)
                soundExtractor.advance()
            } else {
                break
            }
        }

        // copy music
        while (true) {
            val chunkSize = audioExtractor.readSampleData(buffer, 0)

            if (chunkSize > 0 && videoBufferInfo.presentationTimeUs > audioBufferInfo.presentationTimeUs) {
                audioBufferInfo.presentationTimeUs = audioExtractor.sampleTime
                audioBufferInfo.flags = audioExtractor.sampleFlags
                audioBufferInfo.size = chunkSize

                muxer.writeSampleData(audioIndex, buffer, audioBufferInfo)
                audioExtractor.advance()
            } else {
                break
            }
        }


        muxer.stop()
        muxer.release()

        videoExtractor.release()
        soundExtractor.release()
        audioExtractor.release()
    }

The problem is that the Audio Stream is split into two parts .问题是音频 Stream 被分成两部分 When I use ffmpeg to combine AudioStream into one and then mux audio file and video file in to a mp4 file, the problem is solved.当我使用ffmpeg将AudioStream合并为一个,然后将音频文件和视频文件混合成一个mp4文件时,问题就解决了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM