Golang+FFmpeg

Kate

Administrator
Команда форума
Долго искал более-менее живую Golang-библиотеку для работы с rtsp.

Изначально наткнулся на github.com/nareix/joy4, но там оказался устаревший C-код и rtp был на Golang, а декодинг на FFmpeg. (немало deprecated варнингов).
Изначально форкнул ее, что-то поправил, но с китайскими камерами (о чем, много уже, написано на хабре), часто были битые кадры, отвалы коннекта и т.д.
Поискал по Go-go! telegram-чату - понял, что нет хороших решений.

Ну и как любят делать на JS - нужно написать свой фреймворк)

Поискал примеры rtsp-клентов на c/c++, перенес все это на Golang, декодинг взял из наработок github.com/Danile71/joy4.

Пока что заложил логику довольно статичную - открываем rtsp/mjpeg/file

  • видео превращается в jpeg
  • аудио в pcm wav
Для подключения к rtsp - имеется возможность выбрать Tcp/Udp/Auto подключение.
Локальные файлы передавать путем до файла.
Проверил на (ffmpeg version 4.2.4-1ubuntu0.1):

  • RTSP (H264/AAC)
  • RTSP (H265/AAC)
  • MJPEG
  • MP4 (H264/AAC)
  • AVI (H264/AAC)
  • FLAC
  • WAV
  • MP3
  • MPEG2 TS(H265/AAC)
Пример

package main

import (
"io"
"net/http"
"os"

"github.com/Danile71/go-logger"
"github.com/Danile71/go-rtsp"
"github.com/gorilla/mux"
"github.com/mattn/go-mjpeg"
)

//const uri = "rtsp://admin:admin@127.0.0.1:554"

const uri = "./file.ts"

func main() {
s := mjpeg.NewStream()

f, err := os.Create("./audio.pcm")
if logger.OnError(err) {
return
}
defer f.Close()

// Call stream.Setup(Auto)
stream, err := rtsp.Open(uri)
if logger.OnError(err) {
return
}

// Custom setup call
// stream := rtsp.New(uri)
// err = stream.Setup(rtsp.Tcp)
// if logger.OnError(err) {
// return
// }

go func() {

for {
pkt, err := stream.ReadPacket()
if logger.OnError(err) {
if err == io.EOF {
os.Exit(1)
}
continue
}

if pkt.IsVideo() {
// pkt.Width()
// pkt.Height()
s.Update(pkt.Data())
}

if pkt.IsAudio() {
// pkt.SampleRate()
// pkt.Channels()
// pkt.BitRate()
_, err := f.Write(pkt.Data())
if logger.OnError(err) {
continue
}
}
}
}()

streamHandler := func(w http.ResponseWriter, r *http.Request) {
s.ServeHTTP(w, r)
}

router := mux.NewRouter()
router.HandleFunc("/stream", streamHandler)
http.Handle("/", router)
http.ListenAndServe(":8181", nil)
}
c6cb07f3d9e4caad0357918f4f27dc35.png


Сие творение: github.com/Danile71/go-rtsp

Источник статьи: https://habr.com/ru/post/569162/
 
Сверху