首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Applet 網頁錄音機實作:Windows API 採樣、GSM 壓縮、AU 串流播放

     編輯:Java 相關知識

早期 Web 多媒體應用中,透過 Java Applet 嵌入網頁實現「錄音→壓縮→儲存→播放」完整鏈路。本文詳細拆解錄音機核心模組:Visual J++ J/Direct 呼叫 Windows winmm.dll 進行低延遲採樣、GSM 6.10 壓縮編碼、靜音區段偵測與資料頭標記、雙執行緒緩衝區解碼播放 AU 格式,並提供關鍵原始碼片段。

音訊基礎參數

參數設定值說明
採樣率8 kHz符合奈奎斯特定理,涵蓋語音頻帶 300~3400 Hz
量化位數16-bit動態範圍 96 dB,足夠語音品質
聲道單聲道資料量減半,適合網路傳輸
採樣塊大小1600 bytes (0.1 秒)回呼頻率 10 Hz,平衡延遲與 CPU

三大核心模組

1. 音訊採集

繞過 Java Sound API,直接以 J/Direct 映射 waveInOpen/PrepareHeader/AddBuffer/Start/Stop,利用回呼函數 Callback 於獨立執行緒推送 PCM 區塊,無需額外錄音執行緒。

// 關鍵類別結構
class AudioCapture {
    WAVEINCAPS waveincaps;
    WAVEHDR[] wavehdr;
    Vector listeners;
    native int waveInOpen(...);
    native int waveInAddBuffer(...);
    native int waveInStart(int hwi);
    private class CallbackImpl extends Callback { ... } // J/Direct 回呼
    synchronized void notifyListener(int minValue, byte[] audioData) { ... }
}

2. 壓縮編碼與靜音偵測

採用 GSM 6.10(壓縮比 10:1,品質尚可、速度中等)。每 0.1 秒區塊計算最小量化值 minValue,若為 0 視為靜音,僅寫入資料頭 0;否則寫入 1 + 壓縮資料體。

public void onAudioDataArrived(AudioDataEvent evt) {
    int min = evt.getAudioMinValue();
    fileWriter.write(min == 0 ? 0 : 1);
    if (min != 0) {
        Convert.BytesToInts(evt.getAudioData(), audioData);
        fileWriter.write(Codec.encode(evt.getAudioData())); // GSM encode
    }
}

檔案結構:[Header][Body][Header][Body]...,Header=1 byte,Body=33 bytes (GSM) 或 0 byte (靜音)。

3. AU 串流播放

Java Applet 原生支援 AU 格式,sun.audio.AudioPlayer.start(InputStream) 每 50ms 讀取 400 bytes。為避免解壓阻塞播放執行緒,採用「生產者-消費者」雙執行緒 + 環狀緩衝區:

  • 解壓執行緒:讀檔→處理靜音標記→GSM decode→寫入 AudioBuffer(InputStream 子類)。
  • 播放執行緒:JVM 內部定時呼叫 read() 取資料播放。
  • AudioBuffer 以 wait/notify 同步,支援 suspend/resume/close 控制。
class AudioBuffer extends InputStream {
    byte[] data = new byte[4096];
    int readPtr, writePtr, usedBytes, emptyBytes;
    synchronized int read(byte[] buf, int off, int len) { ... } // 消費者
    synchronized void write(byte[] buf, int off, int len) { ... } // 生產者
}
class AudioPlayer implements Runnable {
    AudioBuffer buffer = new AudioBuffer(this);
    public void run() {
        while (!isClose) {
            fileIn.read(compressData);      // 讀壓縮資料
            Codec.decode(compressData, auData); // 解壓
            buffer.write(auData, 0, 400);   // 推入緩衝區
        }
    }
    // 啟動播放
    sun.audio.AudioPlayer.start(buffer);
}

壓縮格式比較

格式壓縮比檔案大小音質編解碼速度資料率
GSM 6.1010:1極小普通慢165 B/s
IMA ADPCM4:1小良好快400 B/s
AU (μ-law)2:1中良好極快800 B/s

擴充應用方向

  • 語音留言板(錄音→上傳 Servlet→儲存→播放)
  • 即時語音聊天(Multicast Socket 傳送壓縮封包→對端解碼播放)
  • 語音合成(預錄音素庫→文字轉語音拼接)
  • 跳躍播放(在 AudioBuffer 實現 skip() 對應 UI 滑桿)

現代化替代方案

Applet/NPAPI 已被瀏覽器封殺,現代 Web 應用請改用:

  1. Web Audio API + MediaRecorder API:瀏覽器原生錄音、編碼 (Opus/WebM)、串流播放。
  2. WebRTC:即時語視訊、回聲消除、頻寬自適應。
  3. WebAssembly:移植 C/C++ 編碼器 (libopus, speex) 至瀏覽器高效執行。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved