Как стать автором
Обновить

Golang+FFmpeg

Время на прочтение2 мин
Количество просмотров13K

Долго искал более-менее живую 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)
}

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

p.s. Имеется ли у кого интерес к медиа направлению на Golang?

Теги:
Хабы:
Всего голосов 4: ↑2 и ↓20
Комментарии7

Публикации

Истории

Работа

Go разработчик
149 вакансий

Ближайшие события

3 – 18 октября
Kokoc Hackathon 2024
Онлайн
10 – 11 октября
HR IT & Team Lead конференция «Битва за IT-таланты»
МоскваОнлайн
25 октября
Конференция по росту продуктов EGC’24
МоскваОнлайн
7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн