android - 使用 Android MediaRecorder 暂停和恢复(API 级别 < 24)

标签 android merge mediarecorder mpeg-4 pause

在使用 MediaRecorder 时,我们没有 API 级别低于 24 的暂停/恢复功能。 所以有一种方法可以做到这一点:

  1. 在暂停事件中停止记录器并创建记录的文件。
  2. 在恢复时再次开始录制并创建另一个文件并继续这样做直到用户按下停止。
  3. 最后合并所有文件。

很多人在SO上问过这个问题,但无论如何都找不到解决这个问题的办法。人们谈论通过在暂停操作时停止录制并在恢复时重新启动来创建多个媒体文件。所以我的问题是我们如何以编程方式合并/加入所有媒体文件?

注意:在我的例子中是 MPEG4 容器 - m4a 用于音频,mp4 用于视频。

我尝试使用 SequenceInputStream 合并各个生成的记录文件的多个 InputStream。但它总是只产生第一个文件。

代码 fragment :

Enumeration<InputStream> enu = Collections.enumeration(inputStreams);
        SequenceInputStream sqStream = new SequenceInputStream(enu);
        while ((oneByte = sqStream.read(buffer)) != -1) {
            fileOutputStream.write(buffer, 0, oneByte);

        }
        sqStream.close();
        while (enu.hasMoreElements()) {
            InputStream element = enu.nextElement();
            element.close();
        }
        fileOutputStream.flush();
        fileOutputStream.close();

最佳答案

我可以使用 mp4parser 解决这个问题图书馆。非常感谢这个库的作者:)

在您的 gradle 文件中添加以下依赖项:

compile 'com.googlecode.mp4parser:isoparser:1.0.2'

解决方案是在用户暂停时停止记录器并在恢复时重新开始,正如 stackoverflow 中许多其他答案中已经提到的那样。将生成的所有音频/视频文件存储在一个数组中,并使用以下方法合并所有媒体文件。该示例也取自 mp4parser 库,并根据我的需要进行了一些修改。

public static boolean mergeMediaFiles(boolean isAudio, String sourceFiles[], String targetFile) {
        try {
            String mediaKey = isAudio ? "soun" : "vide";
            List<Movie> listMovies = new ArrayList<>();
            for (String filename : sourceFiles) {
                listMovies.add(MovieCreator.build(filename));
            }
            List<Track> listTracks = new LinkedList<>();
            for (Movie movie : listMovies) {
                for (Track track : movie.getTracks()) {
                    if (track.getHandler().equals(mediaKey)) {
                        listTracks.add(track);
                    }
                }
            }
            Movie outputMovie = new Movie();
            if (!listTracks.isEmpty()) {
                outputMovie.addTrack(new AppendTrack(listTracks.toArray(new Track[listTracks.size()])));
            }
            Container container = new DefaultMp4Builder().build(outputMovie);
            FileChannel fileChannel = new RandomAccessFile(String.format(targetFile), "rw").getChannel();
            container.writeContainer(fileChannel);
            fileChannel.close();
            return true;
        }
        catch (IOException e) {
            Log.e(LOG_TAG, "Error merging media files. exception: "+e.getMessage());
            return false;
        }
    }

对音频文件使用标志 isAudio 为 true,对视频文件使用 false。

关于android - 使用 Android MediaRecorder 暂停和恢复(API 级别 < 24),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39321420/

相关文章:

android - 是否有创建操作按钮 fragment 的简单方法?

Android:有人可以帮助我了解如何在一个 Activity 中的多个 View 和布局之间切换吗?

python - 合并数据帧时如何合并两个列表列?

Git: merge stash 了某些更改

android - MediaRecorder - 固件升级后代码停止工作

android - 在 sencha touch 2 中解析 json

c# - 我计算智能手机位置的算法 - GPS 和传感器

c - 合并两个文件,为什么在末尾添加一个新行? C编程

android - MediaRecorder.stop() 停止失败 : -1007

android - 在 android 7 的通话录音中听不到来电?