ホームページ  >  記事  >  バックエンド開発  >  Go 言語を使用してオーディオおよびビデオの処理とストリーミング メディア開発を行う方法

Go 言語を使用してオーディオおよびビデオの処理とストリーミング メディア開発を行う方法

PHPz
PHPzオリジナル
2023-08-05 17:53:072866ブラウズ

Go 言語を使用してオーディオおよびビデオの処理およびストリーミング メディア開発を行う方法

はじめに:
インターネットの急速な発展とネットワーク帯域幅の継続的な改善により、オーディオおよびビデオのアプリケーションはますます重要になっています。ますます普及していきます。 Go 言語は、同時実行性が高く、高性能なプログラミング言語として、徐々に開発者の注目を集めています。この記事では、オーディオとビデオのフォーマット処理、オーディオとビデオのエンコードとデコード、オーディオとビデオの送信とストリーミング、ストリーミング メディア サーバーの構築など、オーディオとビデオの処理とストリーミング メディア開発に Go 言語を使用する方法を紹介します。 。

1. オーディオおよびビデオ形式の処理
オーディオおよびビデオ処理では、一般的なオーディオおよびビデオ形式には MP3、AAC、WAV、FLV、MP4 などが含まれます。 Go 言語は、これらのオーディオおよびビデオ形式を簡単に処理できる優れたライブラリをいくつか提供します。以下では、MP3 ファイルの処理を例に説明します。

Go 言語では、サードパーティのライブラリ「github.com/hajimehoshi/go-mp3」を使用して MP3 ファイルを処理できます。まずライブラリをインストールする必要があります:

go get github.com/hajimehoshi/go-mp3/mp3

次に、次のコード例を使用して MP3 ファイルを読み取り、オーディオ データを出力します。

package main

import (

"fmt"
"github.com/hajimehoshi/go-mp3/mp3"
"github.com/hajimehoshi/oto"
"os"

)

func main() {

file, err := os.Open("test.mp3")
if err != nil {
    fmt.Println("Open file failed:", err)
    return
}
defer file.Close()

decoder, err := mp3.NewDecoder(file)
if err != nil {
    fmt.Println("NewDecoder failed:", err)
    return
}

pcm, err := oto.NewPlayer(decoder.SampleRate(), 2, 2, 8192)
if err != nil {
    fmt.Println("NewPlayer failed:", err)
    return
}
defer pcm.Close()

fmt.Println("Playing...")

buffer := make([]byte, 8192)
for {
    n, err := decoder.Read(buffer)
    if err != nil {
        fmt.Println("Read failed:", err)
        break
    }
    if n == 0 {
        break
    }
    pcm.Write(buffer[:n])
}

fmt.Println("Done.")

}

# #In上記のコードでは、mp3.NewDecoder 関数を使用して MP3 デコーダーを作成し、oto.NewPlayer 関数を使用してオーディオ プレーヤーを作成します。次に、Read メソッドを使用してオーディオ データを読み取り、Write メソッドを使用して再生するためにプレーヤーにオーディオ データを書き込みます。

2. オーディオとビデオのエンコードとデコード

オーディオとビデオの処理において、エンコードとデコードは非常に重要な部分です。 Go 言語は、ffmpeg、opus、x264 などの優れたエンコードおよびデコード ライブラリを提供します。これらのライブラリのほとんどは Go 言語のカプセル化を提供しており、使用は比較的簡単です。

以下では、ffmpeg ライブラリを例として、オーディオとビデオのエンコードとデコードに Go 言語を使用する方法を紹介します。まず、ffmpeg ライブラリをインストールする必要があります。

go get github.com/giorgisio/goav/avcodec

go get github.com/giorgisio/goav/avformat

次に、 MP3 ファイルを AAC ファイルにエンコードする次のコード例:

package main

import (

"github.com/giorgisio/goav/avcodec"
"github.com/giorgisio/goav/avformat"
"github.com/giorgisio/goav/avutil"
"os"

)

func main() {

inputFile := "input.mp3"
outputFile := "output.aac"

// 注册所有的编解码器
avcodec.AvcodecRegisterAll()

inputContext := avformat.AvformatAllocContext()
if avformat.AvformatOpenInput(&inputContext, inputFile, nil, nil) < 0 {
    panic("Open input file failed.")
}
defer avformat.AvformatFreeContext(inputContext)

if avformat.AvformatFindStreamInfo(inputContext, nil) < 0 {
    panic("Find stream info failed.")
}

audioStreamIndex := -1
for i := 0; i < len(inputContext.Streams()); i++ {
    if inputContext.Streams()[i].CodecParameters().CodecType() == avutil.AVMEDIA_TYPE_AUDIO {
        audioStreamIndex = i
        break
    }
}

codecParameters := inputContext.Streams()[audioStreamIndex].CodecParameters()
codecId := codecParameters.CodecId()
codec := avcodec.AvcodecFindDecoder(codecId)
if codec == nil {
    panic("Find decoder failed.")
}

codecContext := avcodec.AvcodecAllocContext3(codec)
if codecContext == nil {
    panic("Allocate codec context failed.")
}
defer avcodec.AvcodecFreeContext(codecContext)

if avcodec.AvcodecParametersToContext(codecContext, codecParameters) < 0 {
    panic("Parameters to context failed.")
}

if avcodec.AvcodecOpen2(codecContext, codec, nil) < 0 {
    panic("Open codec failed.")
}
defer avcodec.AvcodecClose(codecContext)

outputFileContext := avformat.AvformatAllocOutputContext2()
if avformat.AvformatAllocOutputContext2(&outputFileContext, nil, "adts", outputFile) < 0 {
    panic("Allocate output context failed.")
}
defer avformat.AvformatFreeContext(outputFileContext)

outputStream := avformat.AvformatNewStream(outputFileContext, nil)
if outputStream == nil {
    panic("New stream failed.")
}

if avcodec.AvcodecParametersFromContext(outputStream.CodecParameters(), codecContext) < 0 {
    panic("Parameters from context failed.")
}

if outputStream.CodecParameters().CodecType() != avutil.AVMEDIA_TYPE_AUDIO {
    panic("Codec type is not audio.")
}

if avformat.AvioOpen(&outputFileContext.Pb(), outputFile, avformat.AVIO_FLAG_WRITE) < 0 {
    panic("Open output file failed.")
}

if avformat.AvformatWriteHeader(outputFileContext, nil) < 0 {
    panic("Write header failed.")
}
defer avformat.AvWriteTrailer(outputFileContext)

packet := avcodec.AvPacketAlloc()
defer avcodec.AvPacketFree(packet)

for avcodec.AvReadFrame(inputContext, packet) >= 0 {
    if packet.StreamIndex() == audioStreamIndex {
        packet.SetPts(packet.Pts() * 2)
        packet.SetDts(packet.Dts() * 2)
        packet.SetDuration(packet.Duration() * 2)
        packet.SetPos(-1)

        if avcodec.AvInterleavedWriteFrame(outputFileContext, packet) < 0 {
            panic("Interleaved write frame failed.")
        }
    }
    avcodec.AvPacketUnref(packet)
}

}

上記のコードでは、ffmpeg ライブラリを使用して入力 MP3 ファイルをデコードし、デコードされたオーディオ データをエンコードして、エンコードされたデータを出力ファイルに書き込みます。

3. オーディオとビデオの送信とストリーミング

オーディオとビデオの送信とストリーミングは、リアルタイムのオーディオとビデオの送信とストリーミング メディア サービスを実現するための鍵であり、非常に複雑なリンクでもあります。現在、最も一般的に使用されているオーディオおよびビデオ伝送プロトコルは RTMP と HLS です。 Go 言語は、RTMP および HLS プロトコルのプッシュおよびプル ストリーミングを簡単に実装できる優れたライブラリをいくつか提供します。

以下では、RTMP プロトコルを例として、オーディオとビデオの送信とストリーミングに Go 言語を使用する方法を紹介します。まず、rtmp ライブラリをインストールする必要があります。

go get github.com/gwuhaolin/livego/protocol/rtmp

go get github.com/gwuhaolin/livego/av/codec
go get github.com/gwuhaolin/livego/container

次に、次のコード例を使用して、カメラのビデオ データを RTMP サーバーにプッシュします:

package main

import (

"github.com/gwuhaolin/livego/protocol/rtmp"
"github.com/gwuhaolin/livego/av/codec"
"github.com/gwuhaolin/livego/container"
"os"

)

func main() {

inputFile := "/dev/video0"
outputURL := "rtmp://localhost/live/stream"

inputCodec := codec.NewVideoCodec(codec.H264)
outputCodec := codec.NewVideoCodec(codec.H264)

container := container.NewPushContainer(inputFile, inputCodec, outputURL, outputCodec)
container.Push()

}

上記のコードでは、rtmp ライブラリによって提供される RTPMPusher クラスを使用して、カメラのビデオ データが RTMP サーバーにプッシュされます。このうち、inputFileは入力ファイル(カメラデバイスファイル)、outputURLはプッシュアドレスです。

4. ストリーミング メディア サーバーの構築

ストリーミング メディア開発において、ストリーミング メディア サーバーは、リアルタイムの音声や映像の伝送、オンデマンド機能を実現するための中核となるコンポーネントです。現在、一般的に使用されているストリーミング メディア サーバーには、Nginx-rtmp、FFmpeg、GStreamer などが含まれます。

このセクションでは、Nginx-rtmp を例として、Nginx-rtmp を使用してストリーミング メディア サーバーを構築する方法を紹介します。 Nginx-rtmp は、オーディオ データとビデオ データを RTMP サーバーにプッシュでき、RTMP サーバーからオーディオ データとビデオ データをプルすることもできます。

    まず、Nginx と Nginx-rtmp モジュールをインストールする必要があります:
wget http://nginx.org/download/nginx-1.18.0.tar。 gz

tar zxf nginx-1.18.0.tar.gz
cd nginx-1.18.0
./configure --add-module=/path/to/nginx-rtmp-module
make
make install

    Nginx 構成ファイルを変更します:
rtmp {

server {
    listen 1935;
    chunk_size 4000;
    application live {
        live on;
        record off;
    }
    application hls {
        live on;
        hls on;
        hls_path /path/to/hls;
        hls_fragment 5s;
        hls_playlist_length 30s;
    }
}

}

上記の構成では、 live と hls の 2 つのアプリケーションがあると定義します。このうち、ライブ アプリケーションはリアルタイムの音声とビデオの送信に使用され、hls アプリケーションはオンデマンド サービスに使用されます。

    Nginx-rtmp サービスを開始します:
/path/to/nginx/sbin/nginx -c /path/to/nginx/conf/nginx.conf

    プッシュして再生:
プッシュ:

ffmpeg -re -i /path/to/source -c:v copy -c:a copy -f flv rtmp ://localhost/live/stream

Play:

ffplay rtmp://localhost/live/stream

要約:

この記事では、Go 言語のオーディオとビデオ処理とストリーミングメディアの開発。オーディオとビデオのフォーマット処理、オーディオとビデオのエンコードとデコード、オーディオとビデオの送信とストリーミング、ストリーミング メディア サーバーの構築を学ぶことで、オーディオとビデオのテクノロジをより深く理解し、応用し、さまざまなリッチ オーディオとビデオを実装できます。アプリケーション。この記事がオーディオとビデオの開発に興味のある読者に役立つことを願っています。

以上がGo 言語を使用してオーディオおよびビデオの処理とストリーミング メディア開発を行う方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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