2013-03-05 11 views
5

Mam aplikację Go, w której chciałbym przesłać na żywo nieskompresowany dźwięk do przeglądarki. Miałem nadzieję na przesyłanie strumieniowe przez HTTP, po prostu gdy przeglądarka otworzy URL odpowiadający strumieniowi, a następnie zasila to połączenie danymi dźwiękowymi.Kontener do strumieniowania dla tagu HTML5 <audio>

Planowałem użyć WAV do wysłania danych nieskompresowanych, jednak format pliku WAV wymaga, aby rozmiar pliku był wstępnie zdefiniowany w nagłówku. Czy istnieje lepszy format kontenera do robienia tego streamingu, z którym mogę łatwo pracować w Go?

Wiem, że jednym podejściem byłoby użycie odpowiedniego serwera streamingowego i transkodowanie mojego audio przez to, ale jeśli sam to wdrażam, czy istnieje dość prosty sposób na zejście z ziemi? Może biblioteka Go, aby było to łatwiejsze?

Dzięki

EDIT mam rozwiązać ten przez ffmpeg jak wskazano w mojej odpowiedzi poniżej

+1

Napisz otoki wokół otwartego źródła [libvorbis] (http://www.xiph.org/downloads /) biblioteka i zakodować strumień z tym. Może ktoś już zrobił opakowanie, przeszukał internet. – thwd

+2

Jeśli problem został rozwiązany sam, dodaj odpowiedź na swoje własne pytanie i oznacz jako zaakceptowaną odpowiedź. W ten sposób inni ludzie z tym samym problemem będą mogli łatwo zobaczyć rozdzielczość. –

+0

Ok Przyjąłem własną odpowiedź teraz – wxs

Odpowiedz

0

OK, oto, co zrobiłem, mój kod Go przesyła nieprzetworzone dane PCM poprzez proces ffmpeg, który konwertuje go do formatu mp3. Zakładam packets jest kanałem, że moje dane audio są wyświetlane nad i response jest 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

Jeśli nadal myśleć o nieskompresowane WAV na ostateczną jakość to myślę, że masz dwie możliwości

  1. Lie w nagłówku - powiedzieć, że WAV jest bardzo długi (2GB powiedzieć)
  2. Dodaj dodatkowe klocki do pojemnika RIFF

Pierwszy wybór jest łatwy do wdrożenia, ale będzie oznaczać, że naiwne przeglądarki próbują pobrać plik 2 GB zamiast go przesyłać strumieniowo. Mam nadzieję, że cokolwiek implementującego HTML5 nie byłoby naiwne, ale myślę, że musiałbyś to wypróbować.

Drugi wybór, dodając dodatkowe porcje, wydaje się być wspierany przez the RIFF spec, z czego WAV files are a subset. Można wtedy napisać plik WAV z wieloma krótszymi fragmentami danych dźwiękowych. To powinno być obsługiwane przez graczy WAV, ale może nie być tak, jak pliki WAV nigdy nie były szczególnie dobrze ustandaryzowane, i wiele z players just look for a 44 byte header, które nie jest zgodne z RIFF!

Gdybym był tobą, najpierw spróbowałbym pierwszej opcji i zobaczyłbym, jak to działa.

+0

Kłamstwo wydaje się po prostu ... nie tak jakoś. Interesujące byłoby wypróbowanie techniki dodawania kawałków, ale nie na chwilę w kartach. – wxs

Powiązane problemy