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 言語のカプセル化を提供しており、使用は比較的簡単です。
go get github.com/giorgisio/goav/avformat
"github.com/giorgisio/goav/avcodec" "github.com/giorgisio/goav/avformat" "github.com/giorgisio/goav/avutil" "os"
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) }
オーディオとビデオの送信とストリーミングは、リアルタイムのオーディオとビデオの送信とストリーミング メディア サービスを実現するための鍵であり、非常に複雑なリンクでもあります。現在、最も一般的に使用されているオーディオおよびビデオ伝送プロトコルは RTMP と HLS です。 Go 言語は、RTMP および HLS プロトコルのプッシュおよびプル ストリーミングを簡単に実装できる優れたライブラリをいくつか提供します。
go get github.com/gwuhaolin/livego/av/codec
go get github.com/gwuhaolin/livego/container
"github.com/gwuhaolin/livego/protocol/rtmp" "github.com/gwuhaolin/livego/av/codec" "github.com/gwuhaolin/livego/container" "os"
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()
ストリーミング メディア開発において、ストリーミング メディア サーバーは、リアルタイムの音声や映像の伝送、オンデマンド機能を実現するための中核となるコンポーネントです。現在、一般的に使用されているストリーミング メディア サーバーには、Nginx-rtmp、FFmpeg、GStreamer などが含まれます。
tar zxf nginx-1.18.0.tar.gz
cd nginx-1.18.0
./configure --add-module=/path/to/nginx-rtmp-module
make
make install
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; } }
ffmpeg -re -i /path/to/source -c:v copy -c:a copy -f flv rtmp ://localhost/live/stream
ffplay rtmp://localhost/live/stream
この記事では、Go 言語のオーディオとビデオ処理とストリーミングメディアの開発。オーディオとビデオのフォーマット処理、オーディオとビデオのエンコードとデコード、オーディオとビデオの送信とストリーミング、ストリーミング メディア サーバーの構築を学ぶことで、オーディオとビデオのテクノロジをより深く理解し、応用し、さまざまなリッチ オーディオとビデオを実装できます。アプリケーション。この記事がオーディオとビデオの開発に興味のある読者に役立つことを願っています。
以上がGo 言語を使用してオーディオおよびビデオの処理とストリーミング メディア開発を行う方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。