Rumah > Artikel > pembangunan bahagian belakang > Bagaimana untuk menggunakan bahasa Go untuk pemprosesan audio dan video?
Dalam beberapa tahun kebelakangan ini, dengan perkembangan teknologi audio dan video, permintaan untuk teknologi berkaitan pemprosesan audio dan video semakin tinggi. Sebagai bahasa pengaturcaraan berprestasi tinggi, Go juga menyediakan banyak alatan dan perpustakaan yang mudah untuk memudahkan pemprosesan data audio dan video kami. Artikel ini akan memperkenalkan cara menggunakan bahasa Go untuk pemprosesan audio dan video Kandungan khusus adalah seperti berikut:
1 Cara menggunakan Pergi untuk memproses audio
Dalam bahasa Go, memproses data audio biasanya memerlukan penggunaan pengekodan audio perpustakaan Penyahkodan. Pada masa ini yang lebih biasa digunakan termasuk portaudio dan ffmpeg. Di sini kami mengambil ffmpeg sebagai contoh dan memberikan contoh kod mudah untuk membaca fail audio, menukar format dan menyimpan:
package main import ( "github.com/giorgisio/goav/avcodec" "github.com/giorgisio/goav/avformat" "github.com/giorgisio/goav/avutil" "log" ) func main() { // 打开输入文件 inputCtx := avformat.AvformatAllocContext() if err := avformat.AvformatOpenInput(&inputCtx, "input.mp3", nil, nil); err != nil { log.Fatal(err) } defer avformat.AvformatCloseInput(inputCtx) // 查找音频流 if err := avformat.AvformatFindStreamInfo(inputCtx, nil); err != nil { log.Fatal(err) } audioIndex := -1 for i := 0; i < int(inputCtx.NbStreams()); i++ { codecCtx := inputCtx.Streams()[i].Codec() if codecCtx.CodecType() == avutil.AVMEDIA_TYPE_AUDIO { audioIndex = i break } } if audioIndex < 0 { log.Fatal("No audio stream found") } // 打开解码器 codecCtx := inputCtx.Streams()[audioIndex].Codec() codec := avcodec.AvcodecFindDecoder(codecCtx.CodecId()) if codec == nil { log.Fatal("Unsupported codec") } if err := codecCtx.AvcodecOpen2(codec, nil); err != nil { log.Fatal(err) } defer codecCtx.AvcodecClose() // 打开输出文件 outputFmt := avformat.AvGuessFormat("wav", "output.wav", "") if outputFmt == nil { log.Fatal("Failed to guess output format") } outputCtx := avformat.AvformatAllocContext() outputCtx.SetOutputFormat(outputFmt) if err := avformat.AvioOpen(outputCtx.Pb(), "output.wav", avformat.AVIO_FLAG_WRITE); err != nil { log.Fatal(err) } // 写入输出头 if err := avformat.AvformatWriteHeader(outputCtx, nil); err != nil { log.Fatal(err) } // 读取、解码和转换音频帧 for { pkt := avcodec.AvPacketAlloc() defer avutil.AvPacketFree(pkt) if ret := avformat.AvReadFrame(inputCtx, pkt); ret < 0 { if ret == avutil.AVERROR_EOF || ret == avutil.ErrEAGAIN { break } log.Fatal(ret) } if pkt.StreamIndex() != audioIndex { continue } frame := avutil.AvFrameAlloc() defer avutil.AvFrameFree(frame) if _, gotframe, ret := codecCtx.AvcodecDecodeAudio4(pkt, frame); ret >= 0 && gotframe { // 转换格式 if _, _, ret := codecCtx.AvcodecSendPacket(pkt); ret < 0 { log.Fatal(ret) } for { frame2 := avutil.AvFrameAlloc() if _, ret := codecCtx.AvcodecReceiveFrame(frame2); ret == avutil.AvErrorEOF { break } else if ret < 0 { log.Fatal(ret) } if _, ret := avcodec.AvAudioResample(frame2, frame, avformat.AV_SAMPLE_FMT_S16, int(codecCtx.SampleRate()), avformat.AV_SAMPLE_FMT_FLTP, int(codecCtx.SampleRate()), 0, 0); ret < 0 { log.Fatal(ret) } // 写入输出帧 if _, ret := avformat.AvInterleavedWriteFrame(outputCtx, frame); ret != nil { log.Fatal(ret) } } } } // 写入输出尾 if err := avformat.AvWriteTrailer(outputCtx); err != nil { log.Fatal(err) } }
Penerangan kod:
Di sini fungsi avformat.AvformatOpenInput
digunakan untuk membuka fail input dan avformat.AvformatFindStreamInfo
digunakan untuk mencari strim audio.
Gunakan fungsi avcodec.AvcodecFindDecoder
dalam kod untuk mencari penyahkod yang disokong dan bukanya Diandaikan bahawa format pengekodan fail input adalah sah.
Gunakan avformat.AvGuessFormat
untuk mengetahui format pengekodan fail output, kemudian gunakan fungsi avformat.AvformatAllocContext
untuk mencipta konteks fail output dan buka fail.
Gunakan fungsi avformat.AvReadFrame
untuk membaca bingkai daripada fail input dan semak sama ada ia tergolong dalam strim audio. Jika ya, gunakan penyahkod untuk menyahkod bingkai menjadi data audio. Kemudian gunakan fungsi avcodec.AvAudioResample
untuk menukar data audio kepada kadar sampel dan format yang ditetapkan. Akhir sekali, gunakan fungsi avformat.AvInterleavedWriteFrame
untuk menulis bingkai output pada fail output.
2. Cara menggunakan Go untuk memproses video
Memproses data video dalam bahasa Go juga memerlukan penggunaan pustaka codec video, dan anda juga boleh menggunakan pustaka alat ffmpeg. Seterusnya, contoh kod mudah untuk membaca fail video, mengekstrak bingkai dan menyimpan diberikan:
package main import ( "github.com/giorgisio/goav/avcodec" "github.com/giorgisio/goav/avformat" "github.com/giorgisio/goav/avutil" "image" "os" ) func main() { // 打开输入文件 inputCtx := avformat.AvformatAllocContext() if err := avformat.AvformatOpenInput(&inputCtx, "input.mp4", nil, nil); err != nil { panic(err) } defer avformat.AvformatCloseInput(inputCtx) // 查找视频流 if err := avformat.AvformatFindStreamInfo(inputCtx, nil); err != nil { panic(err) } videoIndex := -1 for i := 0; i < int(inputCtx.NbStreams()); i++ { codecCtx := inputCtx.Streams()[i].Codec() if codecCtx.CodecType() == avutil.AVMEDIA_TYPE_VIDEO { videoIndex = i break } } if videoIndex < 0 { panic("No video stream found") } // 打开解码器 codecCtx := inputCtx.Streams()[videoIndex].Codec() codec := avcodec.AvcodecFindDecoder(codecCtx.CodecId()) if codec == nil { panic("Unsupported codec") } if err := codecCtx.AvcodecOpen2(codec, nil); err != nil { panic(err) } defer codecCtx.AvcodecClose() // 创建输出文件 output, err := os.Create("output.jpg") if err != nil { panic(err) } defer output.Close() // 提取视频帧 packet := avutil.AvPacketAlloc() defer avutil.AvPacketFree(packet) for { if ret := avformat.AvReadFrame(inputCtx, packet); ret < 0 { if ret == avutil.AVERROR_EOF || ret == avutil.ErrEAGAIN { break } panic(ret) } if packet.StreamIndex() != videoIndex { continue } // 解码视频帧 frame := avutil.AvFrameAlloc() defer avutil.AvFrameFree(frame) if gotframe, ret := codecCtx.AvcodecSendPacket(packet); ret >= 0 && gotframe { for { frame := avutil.AvFrameAlloc() if _, ret := codecCtx.AvcodecReceiveFrame(frame); ret == avutil.AvErrorEOF { break } else if ret < 0 { panic(ret) } // 写入输出文件 img := image.NewRGBA(image.Rect(0, 0, int(frame.Width()), int(frame.Height()))) for y := 0; y < int(frame.Height()); y++ { for x := 0; x < int(frame.Width()); x++ { c := frame.Data(0)[y*frame.Linesize(0)+x*3 : y*frame.Linesize(0)+x*3+3] img.SetRGBA(x, y, color.RGBA{c[0], c[1], c[2], 255}) } } if err := jpeg.Encode(output, img, &jpeg.Options{Quality: 100}); err != nil { panic(err) } break } } } }
Penjelasan kod:
Begitu juga gunakan fungsi avformat.AvformatOpenInput
untuk membuka fail input dan gunakan avformat.AvformatFindStreamInfo
untuk mencari strim video.
Juga gunakan fungsi avcodec.AvcodecFindDecoder
dalam kod untuk mencari penyahkod yang disokong dan membukanya Diandaikan bahawa format pengekodan input fail adalah sah.
Gunakan pakej os terbina dalam Go untuk mencipta fail output dan bukanya.
Gunakan fungsi avformat.AvReadFrame
untuk membaca bingkai daripada fail input dan semak sama ada ia tergolong dalam strim video. Jika ya, gunakan penyahkod untuk menyahkod bingkai menjadi data video. Data video kemudiannya ditukar kepada data imej (di sini ke dalam format JPEG) melalui gelung dan ditulis pada fail output.
Ringkasan
Artikel ini memperkenalkan cara menggunakan bahasa Go untuk memproses data audio dan video. Penghuraian dan pengekodan dan penyahkodan format ialah pautan utama dalam pemprosesan audio dan video Di sini kami menggunakan pustaka alat ffmpeg untuk memproses format audio dan video. Dalam aplikasi sebenar, operasi pemprosesan audio dan video yang lebih kompleks mungkin diperlukan, tetapi rangka kerja kod keseluruhan adalah serupa. Kami berharap kod sampel kami dapat memberikan sedikit bantuan untuk kerja pemprosesan audio dan video anda.
Atas ialah kandungan terperinci Bagaimana untuk menggunakan bahasa Go untuk pemprosesan audio dan video?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!