android m4c 转化为mp4
来源:互联网 发布:人工智能板块龙头股 编辑:程序博客网 时间:2024/06/11 12:08
多媒体软件开发的人几乎没有不知道FFmpeg的, 最近一直在尝试 FFmpeg 的项目,去看的编解码,很费劲。最终我在一个外国的技术贴上看到了这一解决方案,是将一个m4a格式的音频直接转化为mp4, 我使用了完美解决我的问题, 不需要c++ 或 C 实现,直接由android 内置的MediaMuxer 和 MediaCodec实现。
public static final int COMPRESSED_AUDIO_FILE_BIT_RATE = 128000; // 128kbps
public static final int SAMPLING_RATE = 44100;
public static final int CODEC_TIMEOUT_IN_MS = 5000;
public static final int BUFFER_SIZE = 88200;
public static String AUDIO_RECORDING_FILE_NAME;
public static String COMPRESSED_AUDIO_FILE_NAME;
public static String COMPRESSED_AUDIO_FILE_MIME_TYPE = “audio/mp4a-latm”;
private static String LOGTAG = “m4a > mp4”;
COMPRESSED_AUDIO_FILE_NAME = getFileDirectory(); // m4a 文件格式路径
AUDIO_RECORDING_FILE_NAME = getAudioFilePath(); // pcm 文件格式路径
assert (null == COMPRESSED_AUDIO_FILE_NAME);
assert (null == AUDIO_RECORDING_FILE_NAME);
final File filePcm = new File(AUDIO_RECORDING_FILE_NAME);
new Thread(new Runnable() {
@Override
public void run() {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
Log.e(LOGTAG, “PCM” + AUDIO_RECORDING_FILE_NAME);
File inputFile = new File(AUDIO_RECORDING_FILE_NAME);
try {
FileInputStream fis = new FileInputStream(inputFile);
File outputFile = new File(COMPRESSED_AUDIO_FILE_NAME + “audio.m4a”);
if (outputFile.exists()) {
outputFile.delete();
}
try {
MediaMuxer mux = new MediaMuxer(outputFile.getAbsolutePath(), MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
MediaFormat outputFormat = MediaFormat.createAudioFormat(COMPRESSED_AUDIO_FILE_MIME_TYPE, SAMPLING_RATE, 1);
outputFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, COMPRESSED_AUDIO_FILE_BIT_RATE);
MediaCodec codec = MediaCodec.createEncoderByType(COMPRESSED_AUDIO_FILE_MIME_TYPE); codec.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); codec.start(); ByteBuffer[] codecInputBuffers = codec.getInputBuffers(); // Note: Array of buffers ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers(); MediaCodec.BufferInfo outBuffInfo = new MediaCodec.BufferInfo(); byte[] tempBuffer = new byte[BUFFER_SIZE]; boolean hasMoreData = true; double presentationTimeUs = 0; int audioTrackIdx = 0; int totalBytesRead = 0; int percentComplete; do { int inputBufIndex = 0; while (inputBufIndex != -1 && hasMoreData) { inputBufIndex = codec.dequeueInputBuffer(CODEC_TIMEOUT_IN_MS); if (inputBufIndex >= 0) { ByteBuffer dstBuf = codecInputBuffers[inputBufIndex]; dstBuf.clear(); int bytesRead = fis.read(tempBuffer, 0, dstBuf.limit()); if (bytesRead == -1) { // -1 implies EOS hasMoreData = false; codec.queueInputBuffer(inputBufIndex, 0, 0, (long) presentationTimeUs, MediaCodec.BUFFER_FLAG_END_OF_STREAM); } else { totalBytesRead += bytesRead; dstBuf.put(tempBuffer, 0, bytesRead); codec.queueInputBuffer(inputBufIndex, 0, bytesRead, (long) presentationTimeUs, 0); presentationTimeUs = 1000000l * (totalBytesRead / 2) / SAMPLING_RATE; } } } // Drain audio int outputBufIndex = 0; while (outputBufIndex != MediaCodec.INFO_TRY_AGAIN_LATER) { outputBufIndex = codec.dequeueOutputBuffer(outBuffInfo, CODEC_TIMEOUT_IN_MS); if (outputBufIndex >= 0) { ByteBuffer encodedData = codecOutputBuffers[outputBufIndex]; encodedData.position(outBuffInfo.offset); encodedData.limit(outBuffInfo.offset + outBuffInfo.size); if ((outBuffInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0 && outBuffInfo.size != 0) { codec.releaseOutputBuffer(outputBufIndex, false); } else { mux.writeSampleData(audioTrackIdx, codecOutputBuffers[outputBufIndex], outBuffInfo); codec.releaseOutputBuffer(outputBufIndex, false); } } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { outputFormat = codec.getOutputFormat(); Log.e(LOGTAG, "Output format changed - " + outputFormat); audioTrackIdx = mux.addTrack(outputFormat); mux.start(); } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { Log.e(LOGTAG, "Output buffers changed during encode!"); } else if (outputBufIndex == MediaCodec.INFO_TRY_AGAIN_LATER) { // NO OP } else { Log.e(LOGTAG, "Unknown return code from dequeueOutputBuffer - " + outputBufIndex); } } percentComplete = (int) Math.round(((float) totalBytesRead / (float) inputFile.length()) * 100.0); Log.e(LOGTAG, "Conversion % - " + percentComplete); } while (outBuffInfo.flags != MediaCodec.BUFFER_FLAG_END_OF_STREAM && !mStop); fis.close(); mux.stop(); mux.release(); filePcm.delete(); Log.v(LOGTAG, "Compression done ..."); } catch (IOException e) { Log.e(LOGTAG, "IO Exception"); e.printStackTrace(); } } catch (FileNotFoundException e) { Log.e(LOGTAG, "FileNotFound Exception"); e.printStackTrace(); } mStop = false; // Notify UI thread...}
}).start();
- android m4c 转化为mp4
- Android Drawable 转化为 Bitmap
- Android dip转化为px
- Android经纬度转化为距离
- Android 字符串转化为百分比
- Eclipse转化为android版本
- eclipse android 程序 转化为android studio
- 快速转化J2ME程序为Android程序
- Android 中汉字转化为拼音
- Android图片 将Drawable转化为Bitmap
- Android 将Activity转化为DialogActivity
- Android 屏幕适配,转化为dpi
- Android中图片转化为bitmap
- Android 将String转化为int
- Android将BitMap转化为圆形
- 将String转化为int(android)
- Android把drawable转化为bitmap
- Android 将View 转化为bitmap 图片
- 使用Java操作Mongodb
- Hibernate-Criteria查询(4)Annotation
- 使用pdfbox-2.0.1.jar将pdf转换成图片,并且可自定义图片大小
- JAVA设计模式之单例模式
- sqoop学习笔记
- android m4c 转化为mp4
- 获得ip地理信息的几种方法【最全】
- NRF24L01的通信距离
- android.os.Debug统计 GC 次数
- Xcode编译Error ----Undefined symbols for architecture
- centos 安装mysql最新版mysql
- Android ListView在PopupWindow里时wrap_content无效
- 顺时针打印矩阵
- 关于java中类在实例化时的一点疑问