您的当前位置:首页>关注 > 正文

基于androidapi16的音频裁剪代码分享

来源:CSDN 时间:2023-01-05 11:07:49


【资料图】

若有朋友需要WAV 音频裁剪,可以参考我的另外一篇博文——wav 音频裁剪在android开发中,一说到音视频,程序员第一反应肯定是FFMpeg,但是FFMpeg这个库,又复杂,又性能差,如果只想简单的要个音频裁剪的功能,就要去引入这么大的库,完全不值得。然而自从android api 16之后谷歌就开始在音视频方面进行布局,android 18之后继续丰富音视频编码库,让很多android app在不依赖于繁琐jni就能进行一些基础的音视频开发。下面将是基于android api16的对mp3文件进行裁剪的代码例子。当前由于时间问题,先分享最主流的mp3格式的音频裁剪,以后有时间会分享更多其他音频方面的经验。

//适当的调整SAMPLE_SIZE可以更加精确的裁剪音乐  private static final int SAMPLE_SIZE = 1024 * 200;  @TargetApi(Build.VERSION_CODES.JELLY_BEAN)  public static boolean clip(String inputPath, String outputPath, int start, int end){      MediaExtractor extractor = null;      BufferedOutputStream outputStream = null;      try {          extractor = new MediaExtractor();          extractor.setDataSource(inputPath);          int track = getAudioTrack(extractor);          if(track < 0){              return false;          }          //选择音频轨道          extractor.selectTrack(track);          outputStream = new BufferedOutputStream(          new FileOutputStream(outputPath), SAMPLE_SIZE);          start = start * 1000;          end = end * 1000;          //跳至开始裁剪位置          extractor.seekTo(start, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);          while (true){              ByteBuffer buffer = ByteBuffer.allocate(SAMPLE_SIZE);              int sampleSize = extractor.readSampleData(buffer, 0);              long timeStamp = extractor.getSampleTime();              // >= 1000000是要裁剪停止和指定的裁剪结尾不小于1秒,否则可能产生需要9秒音频              //裁剪到只有8.6秒,大多数音乐播放器是向下取整,这样对于播放器变成了8秒,              // 所以要裁剪比9秒多一秒的边界              if(timeStamp > end && timeStamp - end >= 1000000){                  break;              }              if(sampleSize <= 0){                  break;              }              byte[] buf = new byte[sampleSize];              buffer.get(buf, 0, sampleSize);              //写入文件              outputStream.write(buf);              //音轨数据往前读              extractor.advance();          }      } catch (IOException e) {          e.printStackTrace();      }finally {          if(extractor != null){              extractor.release();          }          if(outputStream != null){              try {                  outputStream.close();              } catch (IOException e) {                  e.printStackTrace();              }          }      }      return true;  }  /**   * 获取音频数据轨道   * @param extractor   * @return   */  @TargetApi(Build.VERSION_CODES.JELLY_BEAN)  private static int getAudioTrack(MediaExtractor extractor) {      for(int i = 0; i < extractor.getTrackCount(); i++){          MediaFormat format = extractor.getTrackFormat(i);          String mime = format.getString(MediaFormat.KEY_MIME);          if(mime.startsWith("audio")){              return i;          }      }      return -1;  }

裁剪音乐的步骤在注释中已经写得很明白了,其实用上面简单的代码就能实现音频裁剪了,而且裁剪的音频经过多项硬指标测试是没有问题的。但可能还是有人会怀疑用上述方法是否得到一个“真正”mp3文件。绝大部分情况下,产品经理的需求都是希望裁剪后的音乐除了长度之外,其他的都和原始音频一样,以防不同的播放器由于编解码库的差异,导致播放失败的情况。下面的代码是用来提取音频的关键数据,来比较裁剪之后的音频和原始音频的关键数据是否一样。

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)private static void printMusicFormat(String musicPath){    try {        MediaExtractor extractor = new MediaExtractor();        extractor.setDataSource(musicPath);        MediaFormat format = extractor.getTrackFormat(getAudioTrack(extractor));        Log.i("music", "码率:" + format.getInteger(MediaFormat.KEY_BIT_RATE));        Log.i("music", "轨道数:" + format.getInteger(MediaFormat.KEY_CHANNEL_COUNT));        Log.i("music", "采样率:" + format.getInteger(MediaFormat.KEY_SAMPLE_RATE));    } catch (IOException e) {        e.printStackTrace();    }}

通过反复验证,通过以上方法裁剪的音频除了时间长度之外,其他格式数据都和原始音频一样,裁剪的音频在各种平台(android, IOS, windows,mac)都能正常的播放和使用。

标签:

最新新闻:

新闻放送
Top