先用Java CV的拉流对象实现对音视频的格式转换:
1、音视频转纯音频
2、音频指定采样率和声道
接着手动搞定采用率的位深,对音频做16位位深和小端点转换。最后把转好的字节数组写入文件,这个简单,用一个IO处理流对象搞定,看代码:
import org.bytedeco.javacv.FFmpegFrameGrabber; import org.bytedeco.javacv.Frame; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.ShortBuffer; /** * 音视频转单声道16位16K赫兹小端点pcm音频 */ public class PCMFileProduce { public static void main(String[] args) throws Exception { String path = "E:\BaiduNetdiskDownload\roundDeskS02E01.mp4"; //待转音视频 File file = new File("E:\BaiduNetdiskDownload\pcmTest.pcm"); //目标文件 OutputStream os = new BufferedOutputStream(new FileOutputStream(file)); FFmpegFrameGrabber frameGrabber = FFmpegFrameGrabber.createDefault(path); frameGrabber.setSampleRate(16000); //16K赫兹采样率 frameGrabber.setAudioChannels(1); //单声道 frameGrabber.start(); Frame frame; Buffer buffer; short[] shorts; byte[] bytes; System.out.println("开始转换文件"); while ((frame = frameGrabber.grabSamples()) != null) { if (frame.samples == null) { continue; } buffer = frame.samples[0]; shorts = new short[buffer.limit()]; ((ShortBuffer) buffer).get(shorts); bytes = shortArr2byteArr(shorts, buffer.limit()); os.write(bytes); } os.close(); // 关闭写文件 frameGrabber.close(); // 直接关闭拉流 System.out.println("转换结束"); } /** * 8位字节数组转16位字节数组,也就是16位的采样位深,转小端点字节数组 * * @param shortArr * @param shortArrLen * @return */ private static byte[] shortArr2byteArr(short[] shortArr, int shortArrLen) { byte[] byteArr = new byte[shortArrLen * 2]; ByteBuffer.wrap(byteArr).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(shortArr); return byteArr; } }
看输出:
Connected to the target VM, address: '127.0.0.1:50289', transport: 'socket' 开始转换文件 转换结束 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'E:BaiduNetdiskDownload oundDeskS02E01.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf58.20.100 Duration: 00:39:54.27, start: 0.000000, bitrate: 815 kb/s Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1080x606, 744 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc (default) Metadata: handler_name : VideoHandler Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 64 kb/s (default) Metadata: handler_name : SoundHandler Disconnected from the target VM, address: '127.0.0.1:50289', transport: 'socket' Process finished with exit code 0
比较下ffmpeg和上面代码转换的两个文件:
命令行转换参见:ffmpeg音视频转单声道16位16K赫兹小端点pcm音频