Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Cara menggunakan bahasa go untuk pemprosesan audio dan video serta pembangunan media penstriman

Cara menggunakan bahasa go untuk pemprosesan audio dan video serta pembangunan media penstriman

PHPz
PHPzasal
2023-08-05 17:53:072866semak imbas

Cara menggunakan bahasa Go untuk pemprosesan audio dan video serta pembangunan media penstriman

Pengenalan:
Dengan perkembangan pesat Internet dan peningkatan berterusan lebar jalur rangkaian, aplikasi audio dan video menjadi semakin meluas. Sebagai bahasa pengaturcaraan konkurensi tinggi dan berprestasi tinggi, bahasa Go secara beransur-ansur menarik perhatian pembangun. Artikel ini akan memperkenalkan cara menggunakan bahasa Go untuk pemprosesan audio dan video dan pembangunan media penstriman, termasuk yang berikut: pemprosesan format audio dan video, pengekodan dan penyahkodan audio dan video, penghantaran dan penstriman audio dan video, pembinaan pelayan media penstriman, dsb. .

1. Pemprosesan format audio dan video
Dalam pemprosesan audio dan video, format audio dan video biasa termasuk MP3, AAC, WAV, FLV, MP4, dll. Bahasa Go menyediakan beberapa perpustakaan yang sangat baik yang boleh mengendalikan format audio dan video ini dengan mudah. Berikut mengambil pemprosesan fail MP3 sebagai contoh.

Dalam bahasa Go, kami boleh menggunakan pustaka pihak ketiga "github.com/hajimehoshi/go-mp3" untuk memproses fail MP3. Mula-mula kita perlu memasang perpustakaan:

pergi dapatkan github.com/hajimehoshi/go-mp3/mp3

Seterusnya, kami menggunakan contoh kod berikut untuk membaca fail MP3 dan mengeluarkan data audio:

pakej utama

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.")

}

Dalam kod di atas, kami mencipta penyahkod MP3 menggunakan fungsi mp3.NewDecoder dan mencipta pemain audio melalui fungsi oto.NewPlayer . Kemudian, baca data audio melalui kaedah Baca, dan tulis data audio kepada pemain untuk main semula melalui kaedah Tulis.

2. Pengekodan dan penyahkodan audio dan video
Dalam pemprosesan audio dan video, pengekodan dan penyahkodan adalah bahagian yang sangat penting. Bahasa Go menyediakan beberapa perpustakaan pengekodan dan penyahkodan yang sangat baik, seperti ffmpeg, opus, x264, dsb. Kebanyakan perpustakaan ini menyediakan enkapsulasi bahasa Go dan agak mudah untuk digunakan.

Yang berikut mengambil perpustakaan ffmpeg sebagai contoh untuk memperkenalkan cara menggunakan bahasa Go untuk pengekodan dan penyahkodan audio dan video. Pertama, kita perlu memasang perpustakaan ffmpeg:

pergi dapatkan github.com/giorgisio/goav/avcodec
pergi dapatkan github.com/giorgisio/goav/avformat

Kemudian, gunakan contoh kod berikut untuk mengekod fail MP3 ke AAC Fail:

pakej utama

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

}

Dalam kod di atas, kami menggunakan perpustakaan ffmpeg untuk menyahkod fail MP3 input, dan kemudian menyahkod Enkod data audio dan tulis data yang dikodkan ke fail output.

3 Penghantaran dan penstriman audio dan video
Penghantaran dan penstriman audio dan video adalah kunci untuk merealisasikan perkhidmatan media penstriman dan audio dan video masa nyata, dan ia juga merupakan pautan yang sangat kompleks. Pada masa ini, protokol penghantaran audio dan video yang paling biasa digunakan ialah RTMP dan HLS. Bahasa Go menyediakan beberapa perpustakaan yang sangat baik yang boleh melaksanakan penstriman tolak dan tarik protokol RTMP dan HLS dengan mudah.

Yang berikut mengambil protokol RTMP sebagai contoh untuk memperkenalkan cara menggunakan bahasa Go untuk penghantaran dan penstriman audio dan video. Mula-mula, kita perlu memasang perpustakaan rtmp:

pergi dapatkan github.com/gwuhaolin/livego/protocol/rtmp
pergi dapatkan github.com/gwuhaolin/livego/av/codec
pergi dapatkan github.com/gwuhaolin/livego/ bekas

Kemudian, tolak data video kamera ke pelayan RTMP melalui contoh kod berikut:

pakej utama

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

},

kod di atas kami menggunakan kelas RTPMPusher yang disediakan oleh perpustakaan rtmp untuk menolak data video kamera ke pelayan RTMP. Antaranya, inputFile ialah fail input (fail peranti kamera), dan outputURL ialah alamat push.

4. Pembinaan pelayan media penstriman
Dalam pembangunan media penstriman, pelayan media penstriman adalah komponen teras untuk merealisasikan penghantaran audio dan video masa nyata dan fungsi atas permintaan. Pada masa ini, pelayan media penstriman yang biasa digunakan termasuk Nginx-rtmp, FFmpeg, GStreamer, dll.

Bahagian ini akan mengambil Nginx-rtmp sebagai contoh untuk memperkenalkan cara menggunakan Nginx-rtmp untuk membina pelayan media penstriman. Nginx-rtmp boleh menolak data audio dan video ke pelayan RTMP, dan juga boleh menarik data audio dan video daripada pelayan RTMP.

  1. Mula-mula, kita perlu memasang modul Nginx dan 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

  1. Ubah suai fail konfigurasi Nginx:

rtmpee {

Dalam konfigurasi di atas, kami menentukan dua aplikasi: langsung dan hls. Antaranya, aplikasi langsung digunakan untuk penghantaran audio dan video masa nyata, dan aplikasi hls digunakan untuk perkhidmatan atas permintaan.

    Mulakan perkhidmatan Nginx-rtmp:
/path/to/nginx/sbin/nginx -c /path/to/nginx/conf/nginx.conf

    Tekan dan mainkan:
  1. 🜎Push:
  2. 🜎Push:
🜎 -re -i /path/to/source -c:v copy -c:a copy -f flv rtmp://localhost/live/stream


Main:

ffplay rtmp://localhost/live/stream


Ringkasan :

Artikel ini memperkenalkan cara menggunakan bahasa Go untuk pemprosesan audio dan video serta pembangunan media penstriman. Dengan mempelajari pemprosesan format audio dan video, pengekodan dan penyahkodan audio dan video, penghantaran dan penstriman audio dan video, dan pembinaan pelayan media penstriman, kami boleh lebih memahami dan menggunakan teknologi audio dan video, serta melaksanakan pelbagai audio dan video yang kaya. aplikasi. Saya harap artikel ini dapat membantu pembaca yang berminat dalam pembangunan audio dan video.

Atas ialah kandungan terperinci Cara menggunakan bahasa go untuk pemprosesan audio dan video serta pembangunan media penstriman. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn