【问题标题】:Merging single video track and multiple audio tracks on Android在 Android 上合并单个视频轨道和多个音轨
【发布时间】:2015-10-16 00:46:13
【问题描述】:

想法

我正在为将一个视频轨道与一个(或可选的两个)音频轨道合并的电影编辑应用程序创建保存到设备功能。

首先,我使用 MP4Parser (link) 将多个视频剪辑合并到一个视频轨道

然后,我想将多个音频剪辑合并到单个音轨。这些剪辑不应附加,而应在特定时间合并到单个音轨中。例如。我们有两个音频剪辑(A1、A2)和一个 60 秒的视频轨道(V1)。这些音频剪辑可以重叠,或者在它们之间有白噪声。整个音轨的长度必须与视频轨相匹配,最长可达 60 秒。 最多可以向音轨 1 添加 100 个音频片段

  • V1 - 60.0 秒
  • A1 - 0.3 秒
  • A2 - 1.1 秒

最后,可能还有一个可选的第二个音轨,其中也包含一个音轨,适合 V1 视频轨。

总结

这就是它的样子:

视频轨道 1:[------------------------------------------ --------------------------------------------------] 60 秒

音轨 1:[-A1--A2---------------------- -------------------------------------------] 60 秒

音轨 2:[------------------------------------------ -------------------------------------] 60 秒

问题

我尝试通过将 x 秒的白噪声(空 wav 文件)附加到音轨来解决问题,以获得如上所述的全长音轨,但如果声音重叠,这显然不起作用。我还有什么其他方法可以解决这个问题?

private static final String OUTPUT = "output.mp4";
private static final String STORED_LOCATION = "/storage/emulated/0/"

/**
 * Merges two videos that are located in /storage/emulated/0/ and saves it to the same place with the given parameters. Uses the ffmpeg/javacv library. All this is done in an Async task, not blocking the UI thread but showing a progress bar and a toast at the end.
 *
 */
private void mergeVideosAsync()
{
    new AsyncTask<Void, Void, String>()
    {
        @Override
        protected String doInBackground(Void... arg0)
        {
            try
            {
                List<Movie> movieList = new ArrayList<>();
                for (int i = 0; i < mVideoPathList.size(); ++i)
                {
                    movieList.add(MovieCreator.build(new File(mVideoPathList.get(i)).getAbsolutePath()));
                }

                List<Track> videoTracks = new LinkedList<>();
                List<Track> audioTracks = new LinkedList<>();

                for (Movie m : movieList)
                {
                    for (Track t : m.getTracks())
                    {
                        if (t.getHandler().equals("soun"))
                        {
                            //TODO: Add audio tracks here to the merging process
                            // audioTracks.add(t);
                        }
                        if (t.getHandler().equals("vide"))
                        {
                            videoTracks.add(t);
                        }
                    }
                }
                Movie result = new Movie();
                if (audioTracks.size() > 0)
                {
                    result.addTrack(new AppendTrack(audioTracks.toArray(new Track[audioTracks.size()])));
                }
                if (videoTracks.size() > 0)
                {
                    result.addTrack(new AppendTrack(videoTracks.toArray(new Track[videoTracks.size()])));
                }
                BasicContainer out =  (BasicContainer) new DefaultMp4Builder().build(result);
                mOutputPath = String.format(STORED_LOCATION + File.separator + OUTPUT_FILENAME);
                WritableByteChannel fc = new RandomAccessFile(mOutputPath, "rw").getChannel();
                out.writeContainer(fc);
                fc.close();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            return mOutputPath;
        }
    }.execute();
}

【问题讨论】:

  • 你能解决这个问题吗?如果是的话,你能告诉我们怎么做吗?

标签: android audio video mp4parser


【解决方案1】:

如果您的音轨重叠,那么您将遇到问题,因为您需要重新编码音频。 如果音轨不重叠,那么您也许可以使用 SilenceTrackImpl:

 Track nuAudio = new AppendTrack(
    audioTrackA1, new SilenceTrackImpl(100), 
    audioTrackA2, new SilenceTrackImpl(500),        
    audioTrackA3, new SilenceTrackImpl(1000),
    audioTrackA4, new SilenceTrackImpl(50),
 ) 

等等。

【讨论】:

    猜你喜欢
    • 2011-10-07
    • 2020-03-23
    • 1970-01-01
    • 1970-01-01
    • 2011-12-14
    • 2016-07-05
    • 1970-01-01
    • 1970-01-01
    • 2018-12-10
    相关资源
    最近更新 更多