2013-03-05 47 views
5

我有一個Go應用程序,我想將實時未壓縮的音頻傳輸到瀏覽器。我希望通過瀏覽器打開對應於該流的URL,然後將該連接與音頻數據進行饋送,從而通過HTTP進行流式傳輸。HTML5的流媒體容器<audio>標記

我打算使用WAV發送未壓縮的數據,但WAV文件格式要求在文件頭中預定義文件大小。有沒有更好的容器格式來完成這種流式處理,我可以在Go中輕鬆使用?

我知道一種方法是使用合適的流媒體服務器並通過它轉碼我的音頻,但是如果我自己實現這一點,是否有一種相當直接的方式來實現起飛?可能是一個Go庫來簡化這個過程?

感謝

編輯我已經通過的ffmpeg如下

+1

收件圍繞開源[libvorbis]的包裝(http://www.xiph.org/downloads /)庫並用它編碼你的流。也許有人已經做了一個包裝,搜索互聯網。 – thwd 2013-03-05 19:04:21

+2

如果您自己解決了問題,請爲您的問題添加一個答案,並將其標記爲已接受的答案。這樣,同樣問題的其他人將能夠輕鬆看到解決方案。 – 2013-03-06 06:50:51

+0

好吧,我現在接受了我自己的答案 – wxs 2013-03-07 23:00:58

回答

0

好的,這是我最終做的,我的Go代碼通過一個ffmpeg過程將原始PCM數據傳輸到mp3。我假定packets是,我的音頻數據出現在一個信道,和response是http.ResponseWriter

cmd := exec.Command("ffmpeg", "-v", "verbose", "-f", "u16le", "-ar", "44100", "-ac", "1", "-i", "-", "-f", "mp3", "-") 
audioIn, err := cmd.StdinPipe() 
if err != nil { 
    log.Println("Failed to create stdin pipe") 
} 
audioOut, err := cmd.StdoutPipe() 
if err != nil { 
    log.Println("Failed to create stdout pipe") 
} 
err = cmd.Start() 
if err != nil { 
    log.Println("Failed to start ffmpeg command, error: ", err) 
} 
go func() { 
    for { 
     packet := <-packets 
     audioIn.Write(packet.Payload) 
    } 
} 
go func() { 
    amount, err := io.Copy(response, audioOut) 
    if err != nil { 
     log.Println("io copy terminated with an error", err) 
    } 
    log.Printf("Done copying audio data: %d bytes\n", amount) 
}() 
err = cmd.Wait() 
if err != nil { 
    log.Println("ffmpeg command terminated incorrectly", err) 
} 
2

我的回答概括地解決了這個如果你還在想着未壓縮的WAV文件的最終質量那麼我認爲你有兩個選擇

  1. 橫亙在頭 - 說,WAV很長(2GB說)
  2. 添加額外的塊到RIFF容器

第一種選擇很容易實現,但意味着幼稚的瀏覽器嘗試下載2GB文件而不是流式傳輸。我希望實現HTML5的任何東西都不會那麼天真,但我認爲你需要嘗試一下。

第二種選擇,增加額外的塊似乎支持the RIFF spec其中WAV files are a subset。然後,您可以在其中編寫一個WAV文件,其中包含多個較短的聲音數據塊。這應該得到WAV播放器的支持,但可能並不是WAV文件從未特別標準化過,而且很多players just look for a 44 byte header這不是非常符合RIFF的!

如果我是你,我會先嚐試第一個選項,看看它是如何工作的。

+0

說謊似乎是這樣......不知何故。嘗試塊添加技術會很有趣,但暫時不適用。 – wxs 2013-03-07 22:53:53