Maison  >  Article  >  développement back-end  >  Comment implémenter le protocole HLS en utilisant le langage Go

Comment implémenter le protocole HLS en utilisant le langage Go

PHPz
PHPzoriginal
2023-04-05 09:10:41917parcourir

HLS, HTTP Live Streaming, est un protocole de streaming vidéo proposé par Apple. Sur d'autres plateformes, le protocole HLS peut également être utilisé pour transmettre des flux vidéo. Par exemple, sur la plateforme Android, Google Player (Google ExoPlayer) prend également en charge la lecture de flux vidéo HLS. Le protocole HLS découpe principalement le fichier vidéo original en une série de petits fichiers. Ces petits fichiers sont appelés segments. Ces fragments doivent être codés dans le format de codage correspondant, tel que H.264. Le client obtiendra cette série de fragments via le protocole HTTP. Lorsque le client reçoit un fragment, il commence à le lire. Lorsque ce segment est lu, le client obtiendra le segment suivant et le jouera. De cette façon, une vidéo complète peut être lue.

Le langage Go est un langage très simple, efficace et très adapté à la programmation simultanée. Dans le langage Go, la mise en œuvre du protocole HLS est très simple. Dans cet article, nous présenterons comment implémenter le protocole HLS à l'aide du langage Go.

Tout d’abord, nous devons créer du code de serveur HTTP de base. Cette partie du code est très simple. Il suffit de créer un serveur HTTP avec une adresse et un port d'écoute. Lorsque le client accède au serveur, il peut obtenir un fichier sur le serveur et renvoyer le contenu du fichier au client.

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)
}

Dans ce code, nous créons un serveur HTTP en écoute sur le port 8000. Lorsqu'un client accède à ce serveur, il renvoie le contenu du fichier exemple.mp4 au client.

Ensuite, nous devons écrire du code pour implémenter le découpage du protocole HLS. Cette partie du code est très critique. Le cœur de l'ensemble du protocole HLS consiste à découper un fichier vidéo en plusieurs petits fragments, puis à transmettre ces fragments au client via le protocole HTTP. Nous devons écrire du code pour implémenter cette fonctionnalité.

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)
}

Dans ce code, nous utilisons principalement le package os/exec du langage Go pour exécuter des commandes externes. Il démarrera un processus Shell et exécutera la commande correspondante. Dans cet exemple, nous utilisons la commande ffmpeg pour couper le fichier exemple.mp4 en plusieurs petits segments et enregistrer ces segments dans un répertoire segment. Ensuite, nous pouvons fournir ces fragments au client pour lecture via le protocole HTTP. os/exec 包来执行外部命令。它会启动一个 Shell 进程,并且执行对应的命令。在这个例子中,我们使用了 ffmpeg 命令来将 example.mp4 文件切割成多个小的分片,并且将这些分片保存到一个 segment 目录中。然后,我们就可以通过 HTTP 协议来提供这些分片给客户端播放。

当客户端请求 /out.m3u8 的时候,我们会直接将分片的列表返回给客户端。当客户端请求 /segment/xxx

Lorsque le client demandera /out.m3u8, nous renverrons directement la liste des fragments au client. Lorsque le client demande /segment/xxx, nous devons lire le segment correspondant sur le système de fichiers local et le renvoyer au client.

Enfin, nous avons implémenté avec succès le protocole HLS en utilisant le langage Go. La simplicité et l'efficacité du langage Go conviennent parfaitement à de tels scénarios d'application qui nécessitent une concurrence élevée et un débit élevé. Si vous en avez l'occasion, assurez-vous d'essayer d'implémenter le protocole HLS dans Go. 🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn