HLS, HTTP Live Streaming, ist ein von Apple vorgeschlagenes Video-Streaming-Protokoll. Auf anderen Plattformen kann das HLS-Protokoll auch zur Übertragung von Videostreams verwendet werden. Auf der Android-Plattform unterstützt beispielsweise auch der Google Player (Google ExoPlayer) das Abspielen von HLS-Videostreams. Das HLS-Protokoll schneidet die Originalvideodatei hauptsächlich in eine Reihe kleiner Dateien. Diese kleinen Dateien werden Segmente genannt. Diese Fragmente müssen in das entsprechende Kodierungsformat, z. B. H.264, kodiert werden. Der Client erhält diese Fragmentreihe über das HTTP-Protokoll. Wenn der Client ein Fragment erhält, beginnt er mit der Wiedergabe des Fragments. Wenn dieses Segment abgespielt wird, erhält der Client das nächste Segment und spielt es ab. Auf diese Weise kann ein komplettes Video abgespielt werden.
Go-Sprache ist eine sehr einfache, effiziente und sehr gut für die gleichzeitige Programmierung geeignete Sprache. In der Go-Sprache ist die Implementierung des HLS-Protokolls sehr einfach. In diesem Artikel stellen wir vor, wie das HLS-Protokoll mithilfe der Go-Sprache implementiert wird.
Zuerst müssen wir einen grundlegenden HTTP-Servercode erstellen. Dieser Teil des Codes ist sehr einfach. Wir müssen lediglich einen HTTP-Server mit einer Abhöradresse und einem Port erstellen. Wenn der Client auf den Server zugreift, kann er eine Datei auf dem Server abrufen und den Inhalt der Datei an den Client zurückgeben.
package main import ( "io/ioutil" "net/http" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { data, _ := ioutil.ReadFile("example.mp4") w.Write(data) }) http.ListenAndServe(":8000", nil) }
In diesem Code erstellen wir einen HTTP-Server, der Port 8000 überwacht. Wenn ein Client auf diesen Server zugreift, gibt er den Inhalt der Datei example.mp4 an den Client zurück.
Als nächstes müssen wir Code schreiben, um das Slicing des HLS-Protokolls zu implementieren. Dieser Teil des Codes ist sehr kritisch. Der Kern des gesamten HLS-Protokolls besteht darin, eine Videodatei in viele kleine Fragmente zu zerschneiden und diese Fragmente dann über das HTTP-Protokoll an den Client zu übertragen. Wir müssen Code schreiben, um diese Funktionalität zu implementieren.
package main import ( "bytes" "fmt" "io/ioutil" "net/http" "os" "os/exec" "path/filepath" ) func main() { // 执行 ffmpeg 命令将 example.mp4 文件切割成小的分片 segmentDir := "segment" if _, err := os.Stat(segmentDir); os.IsNotExist(err) { os.Mkdir(segmentDir, os.ModePerm) } cmd := exec.Command("ffmpeg", "-i", "example.mp4", "-profile:v", "baseline", "-level", "3.0", "-start_number", "0", "-hls_time", "10", "-hls_list_size", "0", "-f", "hls", filepath.Join(segmentDir, "out.m3u8")) err := cmd.Run() if err != nil { fmt.Println("exec cmd failed") panic(err) } // 启动 HTTP 服务器用于客户端获取切片文件 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/out.m3u8" { // 获取 m3u8 文件的内容,此文件是一个播放列表,里面包含了可以播放的 ts 文件的序列 data, _ := ioutil.ReadFile(filepath.Join(segmentDir, "out.m3u8")) w.Write(data) } else if len(r.URL.Path) > len("/segment/") && r.URL.Path[0:9] == "/segment/" { // 如果客户端要求播放某个 ts 文件,那么我们就需要从本地文件系统读取这个文件并且返回给客户端 data, _ := ioutil.ReadFile(filepath.Join(segmentDir, r.URL.Path[1:])) http.ServeContent(w, r, "", 0, bytes.NewReader(data)) } }) // 启动 HTTP 服务器 http.ListenAndServe(":8000", nil) }
In diesem Code verwenden wir hauptsächlich das os/exec
-Paket der Go-Sprache, um externe Befehle auszuführen. Es startet einen Shell-Prozess und führt den entsprechenden Befehl aus. In diesem Beispiel verwenden wir den Befehl ffmpeg, um die Datei example.mp4 in mehrere kleine Segmente zu schneiden und diese Segmente in einem segment
-Verzeichnis zu speichern. Anschließend können wir diese Fragmente dem Client zur Wiedergabe über das HTTP-Protokoll bereitstellen. os/exec
包来执行外部命令。它会启动一个 Shell 进程,并且执行对应的命令。在这个例子中,我们使用了 ffmpeg 命令来将 example.mp4 文件切割成多个小的分片,并且将这些分片保存到一个 segment
目录中。然后,我们就可以通过 HTTP 协议来提供这些分片给客户端播放。
当客户端请求 /out.m3u8
的时候,我们会直接将分片的列表返回给客户端。当客户端请求 /segment/xxx
/out.m3u8
anfordert, geben wir die Liste der Shards direkt an den Client zurück. Wenn der Client /segment/xxx
anfordert, müssen wir das entsprechende Segment im lokalen Dateisystem lesen und an den Client zurückgeben. Schließlich haben wir das HLS-Protokoll erfolgreich mit der Go-Sprache implementiert. Die Einfachheit und Effizienz der Go-Sprache eignet sich sehr gut für solche Anwendungsszenarien, die eine hohe Parallelität und einen hohen Durchsatz erfordern. Versuchen Sie bei Gelegenheit unbedingt, das HLS-Protokoll in Go zu implementieren. 🎜Das obige ist der detaillierte Inhalt vonSo implementieren Sie das HLS-Protokoll mithilfe der Go-Sprache. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!