如何使用附加模式将音频录制到现有的音频文件中?

Posted

技术标签:

【中文标题】如何使用附加模式将音频录制到现有的音频文件中?【英文标题】:How can I record audio into existing audio file with append mode? 【发布时间】:2017-10-28 07:11:32 【问题描述】:

如何使用附加模式将音频录制到现有音频文件中,其中包含单个文件中的音频录制。

例子:

我已经录制了 1.amr 文件。播放时间是 00:30 秒,现在我必须再录制 00:20 秒,但文件应该相同,下一次录制应该附加现有的 00:30 秒录制。所以现在播放时间将是 00:50 秒。 在 Java 或 android 中是否可行? 任何图书馆都可以用于此?

【问题讨论】:

您几乎需要将其解码为 wav 并将文件拼接在一起,然后重新编码。 amr 文件被压缩,通常不可能只将数据附加到压缩文件并因此获得有效文件。特别是如果你想做不止一种格式。 感谢您的建议。我只会使用一种格式,对我来说 .wav 可以。但是怎么做呢?你有任何代码示例或库。请告诉我.. 【参考方案1】:

您需要单独录制文件,然后才能将它们合并在一起。

使用 RAW AMR 格式。即将记录器设置设置为:

recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

在 RAW AMR 中生成音频文件后,您可以通过剥离要附加的文件的前 6 个字节来加入这些文件。以二进制模式打开音频文件。

【讨论】:

是的@sahaj,你是救命稻草……经过 2 天的研发,解决了我的问题。【参考方案2】:

我曾经遇到过同样的问题..我发现是..大多数应用程序分别捕获音频然后合并。

实际上,“你不能在录制时这样做”

所以,

如果您对第三方库没有任何问题...可以去这里。

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

代码示例。

import com.coremedia.iso.boxes.Container;
import com.googlecode.mp4parser.authoring.Movie;
import com.googlecode.mp4parser.authoring.Track;
import com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder;
import com.googlecode.mp4parser.authoring.container.mp4.MovieCreator;
import com.googlecode.mp4parser.authoring.tracks.AppendTrack;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * Created by crazy_programmer on 9/25/2017.
 */

public class Audio_util 

    private String dest_file_name;

    public Audio_util(String dest_name) 
        dest_file_name = dest_name;
    


    public String ConcatAudios(File... mp3Files) 

        if(mp3Files == null) return null;

        File mergedFile = new File(dest_file_name);

        for(File fi : mp3Files)
            Log.e("Mod dates",""+fi.lastModified());
        

        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // sort the array for audio sequence

        if (mp3Files.length > 1) 
            Arrays.sort(mp3Files, new Comparator<File>() 
                @Override
                public int compare(File object1, File object2) 
                    return Long.valueOf(object1.lastModified()).compareTo(object2.lastModified());
                
            );
        
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


        for(File fi : mp3Files)
            Log.e("Mod dates 2nd",""+fi.lastModified());
        

        FileOutputStream fos = null;
        String file_name = null;
        try 
            if (!mergedFile.exists()) 
                mergedFile.createNewFile();
            
            Movie[] movies = new Movie[mp3Files.length];
            for (int i = 0; i < mp3Files.length; i++) 
                movies[i] = MovieCreator.build(mp3Files[i].getAbsolutePath());
            

            final Movie finalMovie = new Movie();

            List<Track> audioTracks = new ArrayList<>();
            for (Movie movie : movies) 
                for (Track track : movie.getTracks()) 
                    if (track.getHandler().equals("soun")) 
                        audioTracks.add(track);
                    
                
            

            finalMovie.addTrack(new AppendTrack(audioTracks.toArray(new Track[audioTracks.size()])));

            final Container container = new DefaultMp4Builder().build(finalMovie);
            FileChannel fc = new RandomAccessFile(mergedFile, "rw").getChannel();
            container.writeContainer(fc);
            fc.close();

            if (mergedFile.exists() && mergedFile.length() > 1) 
                file_name = mergedFile.getName();
            

         catch (Exception e) 
            Log.e("mp3Files main excpt", e.getMessage());
         finally 
            try 
                if (fos != null) 
                    fos.flush();
                    fos.close();
                
             catch (IOException e) 
                e.printStackTrace();
            
        
        return file_name;
    



【讨论】:

以上是关于如何使用附加模式将音频录制到现有的音频文件中?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 C#/WPF 录制音频?

快速附加或连接音频文件

在 WPF C# 中使用 NAudio 录制音频

如何编辑或附加录音?

如何保存录制的音频iOS?

如何将绘图附加到现有的 pdf 文件