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

Nit*_*hur 5 merge android mpeg-4 mediarecorder pause

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

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

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

注意:在我的情况下MPEG4容器 - 音频为m4a,视频为mp4.

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

代码片段:

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();
Run Code Online (Sandbox Code Playgroud)

Nit*_*hur 13

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

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

compile 'com.googlecode.mp4parser:isoparser:1.0.2'
Run Code Online (Sandbox Code Playgroud)

解决方案是在用户暂停时停止记录,并在恢复时再次启动,如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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

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