2013-03-05 1 views
5

У меня есть приложение Go, в котором я хотел бы транслировать прямое несжатое аудио в браузер. Я надеялся передать потоки через HTTP, просто открыв браузер URL, соответствующий потоку, а затем подал это соединение с аудиоданными.Streaming container for HTML5 <audio> тег

Я планировал использовать WAV для отправки несжатых данных. Однако для формата файла WAV размер файла должен быть предопределен в заголовке. Есть ли лучший формат контейнера для этой потоковой передачи, с которым я могу легко работать в Go?

Я знаю, что одним из подходов было бы использование надлежащего потокового сервера и перекодирование моего звука через это, но если я сам это реализую, есть ли достаточно простой способ выйти из-под земли? Возможно, библиотека Go, чтобы сделать это проще?

Благодаря

EDIT Я решил эту проблему с помощью FFmpeg, как указано в моем ответе ниже

+1

Написать обертку с открытым исходным кодом [libvorbis] (http://www.xiph.org/downloads /) и кодировать ваш поток с этим. Возможно, кто-то уже сделал обертку, обыскивал интернет. – thwd

+2

Если вы решили проблему самостоятельно, добавьте ответ на свой вопрос и отметьте его как принятый ответ. Таким образом, другие люди с одинаковой проблемой смогут легко увидеть разрешение. –

+0

Хорошо, теперь я принял свой собственный ответ – wxs

ответ

0

Хорошо, вот что я в итоге сделал, мой код Go передает необработанные данные PCM через процесс ffmpeg, который преобразует его в 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

Если вы все еще думаете о несжатого WAVs для максимального качества, то я думаю у вас есть два варианта

  1. Ли в заголовке - говорят, что WAV очень долго (2GB говорят)
  2. Добавить дополнительные куски в RIFF контейнер

Первый выбор прост в реализации, но будет означать, что наивные браузеры пытаются загрузить файл размером 2 ГБ вместо потоковой передачи. Я надеюсь, что что-то, что реализует HTML5, не будет таким наивным, но я думаю, вам нужно попробовать.

Второй вариант, добавляя дополнительные куски, по-видимому, поддерживается the RIFF spec, из которых WAV files are a subset. Затем вы можете записать WAV-файл с несколькими короткими фрагментами звуковых данных внутри. Это должно поддерживаться WAV-плеерами, но может и не быть, поскольку файлы WAV никогда не были особенно хорошо стандартизированы, и много players just look for a 44 byte header, который не очень совместим с RIFF!

Если бы я был вами, я сначала попробую первый вариант и посмотрю, как это работает.

+0

Ложь просто кажется так ... неправильно как-то. Было бы интересно попробовать технику добавления куска, но не в карточках на данный момент. – wxs