1. 程式人生 > 實用技巧 >JavaCV音視訊轉單聲道16位16K赫茲小端點pcm音訊

JavaCV音視訊轉單聲道16位16K赫茲小端點pcm音訊

  先用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\roundDeskS02E01.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音訊