ホームページ  >  記事  >  バックエンド開発  >  Go言語を使用してHLSプロトコルを実装する方法

Go言語を使用してHLSプロトコルを実装する方法

PHPz
PHPzオリジナル
2023-04-05 09:10:41986ブラウズ

HLS (HTTP Live Streaming) は、Apple が提案したビデオ ストリーミング プロトコルです。他のプラットフォームでは、HLS プロトコルを使用してビデオ ストリームを送信することもできます。たとえば、Android プラットフォームでは、Google ExoPlayer も HLS ビデオ ストリームの再生をサポートします。 HLS プロトコルは主に、元のビデオ ファイルを一連の小さなファイルに分割します。これらの小さなファイルはセグメントと呼ばれます。これらのフラグメントは、H.264 などの対応するエンコード形式にエンコードする必要があります。クライアントは、HTTP プロトコルを通じてこの一連のフラグメントを取得します。クライアントはフラグメントを取得すると、そのフラグメントの再生を開始します。このセグメントが再生されると、クライアントは次のセグメントを取得して再生します。このようにして、完全なビデオを再生できます。

Go 言語は非常にシンプルで効率的で、同時プログラミングに非常に適した言語です。 Go 言語では、HLS プロトコルの実装は非常に簡単です。この記事では、Go言語を使用してHLSプロトコルを実装する方法を紹介します。

まず、基本的な HTTP サーバー コードを構築する必要があります。コードのこの部分は非常に単純で、リスニング アドレスとポートを備えた HTTP サーバーを作成するだけです。クライアントがサーバーにアクセスすると、サーバー上のファイルを取得し、そのファイルの内容をクライアントに返すことができます。

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

このコードでは、ポート 8000 でリッスンする HTTP サーバーを作成します。クライアントがこのサーバーにアクセスすると、example.mp4 ファイルの内容がクライアントに返されます。

次に、HLS プロトコルのスライシングを実装するコードを記述する必要があります。コードのこの部分は非常に重要です。 HLS プロトコル全体の中核は、ビデオ ファイルを多数の小さなフラグメントに分割し、これらのフラグメントを HTTP プロトコルを通じてクライアントに送信することです。この機能を実装するにはコードを記述する必要があります。

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

このコードでは、主に Go 言語の os/exec パッケージを使用して外部コマンドを実行します。シェル プロセスが開始され、対応するコマンドが実行されます。この例では、ffmpeg コマンドを使用して example.mp4 ファイルを複数の小さなセグメントに分割し、これらのセグメントを segment ディレクトリに保存します。次に、これらのフラグメントを HTTP プロトコル経由で再生するためにクライアントに提供できます。

クライアントが /out.m3u8 をリクエストすると、シャードのリストをクライアントに直接返します。クライアントが /segment/xxx をリクエストした場合、ローカル ファイル システム上の対応するセグメントを読み取り、クライアントに返す必要があります。

ついに、Go 言語を使用して HLS プロトコルを実装することに成功しました。 Go 言語のシンプルさと効率性は、高い同時実行性と高いスループットを必要とするアプリケーション シナリオに非常に適しています。機会があれば、ぜひ Go に HLS プロトコルを実装してみてください。

以上がGo言語を使用してHLSプロトコルを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。