Android 如何将两个mp3音频文件混合/叠加到一个mp3文件中(不串联)
我想将两个mp3文件合并成一个mp3文件。例如,如果第一个文件是1分钟,第二个文件是30秒,那么输出应该是一分钟。在这一分钟内,它应该播放两个文件。我不确定你是否想在安卓手机上这样做(因为你的标签),但如果我是对的,也许可以尝试,这是一个移动DAW(我自己没有试过) 如果你只是在不调整输出音量的情况下“混合”两个文件,你的输出可能会被剪辑。但是我不确定是否有可能在不解码的情况下“混合”两个mp3文件Android 如何将两个mp3音频文件混合/叠加到一个mp3文件中(不串联),android,audio,merge,mp3,Android,Audio,Merge,Mp3,我想将两个mp3文件合并成一个mp3文件。例如,如果第一个文件是1分钟,第二个文件是30秒,那么输出应该是一分钟。在这一分钟内,它应该播放两个文件。我不确定你是否想在安卓手机上这样做(因为你的标签),但如果我是对的,也许可以尝试,这是一个移动DAW(我自己没有试过) 如果你只是在不调整输出音量的情况下“混合”两个文件,你的输出可能会被剪辑。但是我不确定是否有可能在不解码的情况下“混合”两个mp3文件 如果您可以在PC上合并它们,请尝试,这是一个免费的桌面DAW。首先,为了混合两个音频文件,您需要
如果您可以在PC上合并它们,请尝试,这是一个免费的桌面DAW。首先,为了混合两个音频文件,您需要操纵它们的原始表示法;由于MP3文件是压缩的,您无法直接访问信号的原始表示法。您需要解码压缩后的音频文件MP3流,以便“了解”您的音频信号的波形,然后您将能够混合它们 因此,为了将两个压缩音频文件混合成一个压缩音频文件,需要执行以下步骤:
可以找到更多关于MP3解码器的信息。我没有找到任何好的解决方案。但是我们可以在这里做一些技巧:)
您可以将这两个mp3文件分配给两个不同的MediaPlayer对象。然后使用按钮一次播放这两个文件。比较这两个mp3文件以查找最长的持续时间。然后使用AudioReorder录制到该持续时间。这会解决你的问题。我知道这不是一个正确的方法,但希望它能帮助你 我没有用安卓系统做过,但我是用AdobeFlex做的。我想逻辑是一样的。我遵循以下步骤:
- 我将这两个MP3提取到两个字节的数组中。(
,song1ByteArray
)song2ByteArray
- 找出较大的字节数组。(假设
是较大的一个)song1ByteArray
- 创建一个返回混合字节数组的函数
private ByteArray mix2Songs(ByteArray song1ByteArray, ByteArray song2ByteArray){ int arrLength=song1ByteArray.length; for(int i=0;i<arrLength;i+=8){ // here if you see we are incrementing the length by 8 because a sterio sound has both left and right channels 4 bytes for left +4 bytes for right. // read left and right channel values for the first song float source1_L=song1ByteArray.readFloat();// I'm not sure if readFloat() function exists in android but there will be an equivalant one. float source1_R=song1ByteArray.readFloat(); float source2_L=0; float source2_R=0; if(song2ByteArray.bytesAvailable>0){ source2_L=song1ByteArray.readFloat();//left channel of audio song2ByteArray source2_R=song1ByteArray.readFloat(); //right channel of audio song2ByteArray } returnResultArr.writeFloat((source_1_L+source_2_L)/2); // average value of the source 1 and 2 left channel returnResultArr.writeFloat((source_1_R+source_2_R)/2); // average value of the source 1 and 2 right channel } return returnResultArr; }
private ByteArray mix2Songs(ByteArray song1字节数组、ByteArray song2字节数组){ int arrLength=song1ByteArray.length; 对于(int i=0;i1。 2. 3.您可以利用混合两个音频文件 例如:
4.尝试使用// First convert audiofile to audioinputstream audioInputStream = AudioSystem.getAudioInputStream(soundFile); audioInputStream2 = AudioSystem.getAudioInputStream(soundFile2); // Create one collection list object using arraylist then add all AudioInputStreams Collection list=new ArrayList(); list.add(audioInputStream2); list.add(audioInputStream); // Then pass the audioformat and collection list to MixingAudioInputStream constructor MixingAudioInputStream mixer=new MixingAudioInputStream(audioFormat, list); // Finally read data from mixed AudionInputStream and give it to SourceDataLine nBytesRead =mixer.read(abData, 0,abData.length); int nBytesWritten = line.write(abData, 0, nBytesRead);
混合选项 5.您可以使用所解释的语法和方法在与您类似的项目中使用JLayer库。他还为您提供了如何将该库集成到android应用程序中并直接重新编译jar的指南 解释他的代码很容易完成您的任务:-m
public static byte[] decode(String path, int startMs, int maxMs) throws IOException, com.mindtherobot.libs.mpg.DecoderException { ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024); float totalMs = 0; boolean seeking = true; File file = new File(path); InputStream inputStream = new BufferedInputStream(new FileInputStream(file), 8 * 1024); try { Bitstream bitstream = new Bitstream(inputStream); Decoder decoder = new Decoder(); boolean done = false; while (! done) { Header frameHeader = bitstream.readFrame(); if (frameHeader == null) { done = true; } else { totalMs += frameHeader.ms_per_frame(); if (totalMs >= startMs) { seeking = false; } if (! seeking) { SampleBuffer output = (SampleBuffer) decoder.decodeFrame(frameHeader, bitstream); if (output.getSampleFrequency() != 44100 || output.getChannelCount() != 2) { throw new com.mindtherobot.libs.mpg.DecoderException("mono or non-44100 MP3 not supported"); } short[] pcm = output.getBuffer(); for (short s : pcm) { outStream.write(s & 0xff); outStream.write((s >> 8 ) & 0xff); } } if (totalMs >= (startMs + maxMs)) { done = true; } } bitstream.closeFrame(); } return outStream.toByteArray(); } catch (BitstreamException e) { throw new IOException("Bitstream error: " + e); } catch (DecoderException e) { Log.w(TAG, "Decoder error", e); throw new com.mindtherobot.libs.mpg.DecoderException(e); } finally { IOUtils.safeClose(inputStream); } } public static byte[] mix(String path1, String path2) { byte[] pcm1 = decode(path1, 0, 60000); byte[] pcm2 = decode(path2, 0, 60000); int len1=pcm1.length; int len2=pcm2.length; byte[] pcmL; byte[] pcmS; int lenL; // length of the longest int lenS; // length of the shortest if (len2>len1) { lenL = len1; pcmL = pcm1; lenS = len2; pcmS = pcm2; } else { lenL = len2; pcmL = pcm2; lenS = len1; pcmS = pcm1; } for (int idx = 0; idx < lenL; idx++) { int sample; if (idx >= lenS) { sample = pcmL[idx]; } else { sample = pcmL[idx] + pcmS[idx]; } sample=(int)(sample*.71); if (sample>127) sample=127; if (sample<-128) sample=-128; pcmL[idx] = (byte) sample; } return pcmL; }
公共静态字节[]解码(字符串路径、int-startMs、int-maxMs) 抛出IOException,com.mindtherobot.libs.mpg.DecoderException{ ByteArrayOutputStream扩展流=新的ByteArrayOutputStream(1024); float totalMs=0; 布尔搜索=真; 文件=新文件(路径); InputStream InputStream=新的BufferedInputStream(新文件InputStream(文件),8*1024); 试一试{ Bitstream Bitstream=新比特流(inputStream); 解码器=新解码器(); 布尔完成=假; 而(!完成){ Header-frameHeader=bitstream.readFrame(); if(frameHeader==null){ 完成=正确; }否则{ totalMs+=frameHeader.ms_/u frame(); 如果(totalMs>=startMs){ 寻找=错误; } 如果(!正在查找){ SampleBuffer输出=(SampleBuffer)解码器.decodeFrame(帧头,位流); if(output.getSampleFrequency()!=44100 ||output.getChannelCount()!=2){ 抛出新的com.mindtherobot.libs.mpg.DecoderException(“不支持单声道或非44100 MP3”); } short[]pcm=output.getBuffer(); 用于(简称s:pcm){ 超流写入(s&0xff); 超流写入((s>>8)和0xff); } } 如果(总毫秒>=(起始毫秒+最大毫秒)){ 完成=正确; } } closeFrame(); } 返回outStream.toByteArray(); }捕获(比特流异常e){ 抛出新IOException(“比特流错误:+e”); }捕获(解码){ Log.w(标签“解码器错误”,e); 抛出新的com.mindtherobot.libs.mpg.DecoderException(e); }最后{ IOUtils.safeClose(输入流); } } 公共静态字节[]混合(字符串路径1,字符串路径2){ 字节[]pcm1=解码(路径1,0,60000); 字节[]pcm2=解码(路径2,0,60000); int len1=pcm1.length; int len2=pcm2.1长度; 字节[]pcmL; 字节[]pcmS; int lenL;//最长的长度 int lenS;//最短的长度 if(len2>len1){ lenL=len1; pcmL=pcm1; 透镜=透镜2; pcmS=pcm2; }否则{ lenL=len2; pcmL=pcm2; 透镜=透镜1; pcmS=pcm1; } for(int-idx=0;idx
=镜头){ 样本=pcmL[idx]; }否则{ 样品=pcmL[idx]+pcmS[idx]; } 样本=(int)(样本*.71); 如果(样本>127)样本=127; 如果(sample要合并(重叠)两个声音文件,可以使用 这是你的电话号码 在他们的示例中,您可以只输入所需的命令。因此,让我们讨论一下我们需要的命令
对于第一个和第二个文件路径,您将获得声音文件的绝对路径。 1-如果在sto上-i [FISRST_FILE_PATH] -i [SECOND_FILE_PATH] -filter_complex amerge -ac 2 -c:a libmp3lame -q:a 4 [OUTPUT_FILE_PATH]
-i [FISRST_FILE_PATH] -i [SECOND_FILE_PATH] -filter_complex amerge -ac 2 -c:a libmp3lame -q:a 4 [OUTPUT_FILE_PATH]
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/File Name.mp3"