Heim  >  Artikel  >  Backend-Entwicklung  >  golang rtsp zu http

golang rtsp zu http

WBOY
WBOYOriginal
2023-05-10 17:46:37942Durchsuche

Mit der kontinuierlichen Entwicklung der Internet-Technologie und der Beliebtheit von Netzwerkanwendungen hat die Video-Streaming-Technologie nach und nach große Aufmerksamkeit erlangt. In der Video-Streaming-Technologie ist RTSP ein häufig verwendetes Übertragungsprotokoll für Streaming-Medien, das es Benutzern ermöglicht, Audio- und Videodaten im Netzwerk zu übertragen und abzuspielen. Da das RTSP-Protokoll jedoch während des Übertragungsprozesses das TCP-Protokoll verwendet, ist die Übertragungsgeschwindigkeit relativ langsam und die belegte Bandbreite relativ hoch, was einen gewissen Einfluss auf das Videoerlebnis des Benutzers hat. Um dieses Problem zu lösen, können wir die Methode der Konvertierung des RTSP-Streams in einen HTTP-Stream verwenden, wodurch Bandbreite gespart und die Übertragungsgeschwindigkeit erhöht wird. In diesem Artikel wird erläutert, wie Sie mit Golang den Prozess der Konvertierung von RTSP in http implementieren.

1. Verwenden Sie Golang, um RTSP zu HTTP zu implementieren

Bevor wir RTSP zu HTTP implementieren, müssen wir zunächst den Unterschied zwischen RTSP und HTTP verstehen. Das RTSP-Protokoll muss den Steuerteil des Streaming-Media-Übertragungsprotokolls implementieren, das HTTP-Protokoll implementiert jedoch die statische Seitenübertragung und Datenübertragung. Wenn Sie den RTSP-Stream in einen HTTP-Stream konvertieren möchten, müssen Sie daher eine Zwischenschicht hinzufügen, um die Übertragung des Steuerteils und der statischen HTTP-Seite zu realisieren.

Golang ist eine effiziente, einfache, stabile und hochgradig gleichzeitige Programmiersprache, die sich sehr gut für die Verarbeitung von Audio- und Video-Streaming-Daten in Echtzeit eignet. Aus diesem Grund haben wir uns für die Verwendung von Golang entschieden, um den Prozess der Konvertierung von RTSP in HTTP zu implementieren.

Zuerst müssen wir die Bibliothek in Golang verwenden, um das Parsen und Verarbeiten des RTSP-Protokolls zu implementieren. In Golang gibt es eine Drittanbieter-Bibliothek namens „gosip“, die das Parsen und Verarbeiten des RTSP-Protokolls implementiert. Wir können diese Bibliothek verwenden, um den Prozess der Konvertierung von RTSP in HTTP zu implementieren. Darüber hinaus müssen wir auch die HTTP-Bibliothek in Golang verwenden, um die HTTP-Protokollübertragung zu implementieren.

Die spezifischen Implementierungsschritte lauten wie folgt:

  1. Verwenden Sie zunächst die Gosip-Bibliothek, um die Analyse und Verarbeitung des RTSP-Protokolls zu implementieren.
import (
    "github.com/gorilla/mux"
    "github.com/nareix/srtcp"
    "github.com/nareix/udp"
    "github.com/nareix/webrtc"
    "github.com/nareix/xtcp"
    "github.com/nareix/joy4/format"
    "github.com/nareix/joy4/format/ts"
    "github.com/nareix/joy4/av"
    "github.com/nareix/joy4/container/rtp"
    "github.com/nareix/joy4/av/pubsub"
    "github.com/nareix/joy4/cgo/ffmpeg"
    "github.com/nareix/joy4/av/pktque"
    "net/http"
    "io"
    "fmt"
    "bytes"
    "strconv"
)

...

// 使用gosip库解析RTSP请求
func processRTSP(rtspRequest io.ReadWriteCloser, pubsub1 *pubsub.PubSub, aacWrite io.WriteCloser, h264Write io.WriteCloser) {
    sessionHandle := func(s *rtsp.Session) {
        p, err := s.Streams()
        checkError(err)

        var vtrack av.CodecData
        var atracks []av.CodecData
        for _, vi := range p {
            switch vi.Type().(type) {
            case av.H264CodecData:
                vtrack = vi.(av.H264CodecData)
                break
            case av.AACCodecData:
                atracks = append(atracks, vi.(av.AACCodecData))
                break
            }
        }

        var streamDialers []av.MuxCloser
        var streamWriters []av.MuxCloser

        // 创建H264的PubSub并添加到H264 Pub集
        H264Pub := pubsub.NewSimpleMuxer(100)
        streamDialers = append(streamDialers, H264Pub)
        go func() {
            H264Out := <-H264Pub.Out
            H264Outs, err := rtp.Encode(H264Out, vtrack.(av.VideoCodecData).Sdp())
            checkError(err)
            defer H264Outs.Close()
            n, err := s.WriteInterleaved(H264Outs)
            checkError(err)
            fmt.Println("Sent", n, "bytes. H264")
        }()

        // 创建AAC的PubSub并添加到AAC Pub集
        AACPubs := make([]*pubsub.PubSub, len(atracks))
        for i, atrack := range atracks {
            AACPubs[i] = pubsub.NewSimpleMuxer(100)
            streamDialers = append(streamDialers, AACPubs[i])
            go func(atrack av.CodecData, AACPubs1 *pubsub.PubSub) {
                out := <-AACPubs1.Out
                aacOut, _ := atrack.NewMuxer(out)
                defer aacOut.Close()

                outs, err := rtp.Encode(aacOut, atrack.(av.AudioCodecData).Sdp())
                checkError(err)
                defer outs.Close()
                n, err := s.WriteInterleaved(outs)
                checkError(err)
                fmt.Println("Sent", n, "bytes. Audio")
            }(atrack, AACPubs[i])
        }

        // 打开相应的转换器
        if aacWrite != nil {
            streamWriters = append(streamWriters, aacWrite)
            pubAACOut := make(chan []byte)
            AACPubs[0].Out <- pubAACOut
            go func() { // 把音频包推送到channel,再写到文件 
                for {
                    samples := <-pubAACOut
                    _, err := aacWrite.Write(samples)
                    checkError(err)
                }
            }()
        }
        if h264Write != nil {
            streamWriters = append(streamWriters, h264Write)
            H264Pub.Out <- h264Write
        }

        // 等待停止
        <-s.Done()
        for _, dialer := range streamDialers {
            fmt.Println("Closing dialer")
            dialer.Close()
        }
        for _, writer := range streamWriters {
            fmt.Println("Closing writer")
            writer.Close()
        }
    }

    for {
        req, err := rtsp.NewRequest()
        checkError(err)
        s, err := rtsp.NewSession(req, rtspRequest)
        if err != nil {
            fmt.Println(err)
            break
        }
        sessionHandle(s)
    }
}
  1. Verwenden Sie die HTTP-Bibliothek, um das HTTP-Protokoll zu implementieren und zu übertragen.
...

// 使用HTTP协议请求推送的HLS流
func processHTTP(w http.ResponseWriter, r *http.Request) {
    ctx := &av.Context{Logger: logger}

    fmt.Println("New connection")
    defer fmt.Println("Closing write")

    v := mux.Vars(r)
    streamName := v["name"]

    if r.Method == "GET" {
        fmt.Println("HTTP GET request received...")

        segSeq := 0
        for {
            writer := NewHTTPStreamer(streamName, segSeq, w)
            segSeq++
            pubsub1 := pubsub.NewSimpleMuxer(100)

            // 创建http请求推送流着音视频流
            go func() {
                defer writer.Close()

                fmt.Println("Connected HTTP Writer. Waiting for output.")

                for {
                    Out := <-pubsub1.Out
                    fmt.Println("Received output")
                    ctx := &av.Context{Logger: logger, Write: writer}
                    fmt.Println(ctx)
                    defer ctx.Flush()
                    stream := Out[0]
                    fmt.Println(stream)
                    _ = avutil.CopyPackets(ctx, stream)
                }
            }()
            aacWrite, h264Write := getHLS(path.Join(videoTempDir, streamName), segSeq)
            processRTSP(NewRTSPReader(streamName), pubsub1, aacWrite, h264Write)
        }
    }
}

// 实现HTTP音视频流
func NewHTTPStreamer(base string, sn int, w http.ResponseWriter) *HTTPStreamer {
    str := fmt.Sprintf("%v/%v-%d.ts", videoTempDir, base, sn)
    f, _ := os.Create(str)
    return &HTTPStreamer{Writer: f, ResponseWriter: w}
}

...
  1. Abschließend verbinden wir die RTSP-Anfrage mit der HTTP-Antwort, um den Prozess der Konvertierung von RTSP in HTTP zu realisieren.
...

// 连接RTSP请求和HTTP响应
func streamInvoke(w http.ResponseWriter, r *http.Request) {
    fmt.Println(r.URL.Path)
    if strings.HasPrefix(r.URL.Path, "/stream/") {
        processHTTP(w, r)
    } else if strings.HasPrefix(r.URL.Path, "/hls/") {
        processHLS(w, r)
    } else {
        fmt.Println(r.URL.Path)
        w.WriteHeader(404)
    }
}

...

Das Obige ist die spezifische Implementierungsmethode zur Realisierung des Prozesses der Konvertierung von RTSP in HTTP über Golang. Durch die Konvertierung von RTSP-Streams in HTTP-Streams kann die Übertragung von Videomedien schneller und effizienter gestaltet und so das Seherlebnis des Benutzers verbessert werden.

Das obige ist der detaillierte Inhalt vongolang rtsp zu http. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn