Maison >développement back-end >Golang >Comment utiliser le langage Go pour le traitement audio et vidéo ?
Ces dernières années, avec le développement de la technologie audio et vidéo, la demande de technologies liées au traitement audio et vidéo est devenue de plus en plus élevée. En tant que langage de programmation hautes performances, Go fournit également de nombreux outils et bibliothèques pratiques pour faciliter le traitement des données audio et vidéo. Cet article présentera comment utiliser le langage Go pour le traitement audio et vidéo. Le contenu spécifique est le suivant :
1. Comment utiliser Go pour traiter l'audio
Dans le langage Go, le traitement des données audio nécessite généralement l'utilisation d'un. bibliothèque de codecs audio. Actuellement, les plus couramment utilisés incluent portaudio et ffmpeg. Ici, nous prenons ffmpeg comme exemple et donnons un exemple de code simple pour lire des fichiers audio, convertir des formats et enregistrer :
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) } }
Explication du code :
Utilisez avformat.AvformatOpenInput ici Le
La fonction ouvre le fichier d'entrée et trouve le flux audio à l'aide de avformat.AvformatFindStreamInfo
. avformat.AvformatOpenInput
函数打开输入文件,并使用 avformat.AvformatFindStreamInfo
查找音频流。
在代码中使用 avcodec.AvcodecFindDecoder
函数来查找支持的解码器并打开它,这里假设输入文件的编码格式合法。
使用 avformat.AvGuessFormat
找出输出文件的编码格式,然后使用 avformat.AvformatAllocContext
函数创建输出文件上下文并打开文件。
使用 avformat.AvReadFrame
函数从输入文件中读取帧,并检查它是否属于音频流。如果是,则使用解码器将帧解码为音频数据。然后再使用 avcodec.AvAudioResample
函数将音频数据转换为设定的采样率和格式。最后,使用 avformat.AvInterleavedWriteFrame
函数将输出帧写入输出文件。
二、如何使用 Go 处理视频
在 Go 语言中处理视频数据同样需要使用视频编解码库,同样可以使用 ffmpeg 这个工具库。接下来给出一个简单的读取视频文件、提取帧和保存的示例代码:
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 } } } }
代码解释:
同样是使用 avformat.AvformatOpenInput
函数打开输入文件,并使用 avformat.AvformatFindStreamInfo
查找视频流。
在代码中同样使用 avcodec.AvcodecFindDecoder
函数来查找支持的解码器并打开它,这里假设输入文件的编码格式合法。
使用 Go 内置的 os 包创建输出文件并打开。
使用 avformat.AvReadFrame
avcodec.AvcodecFindDecoder
dans le code pour trouver le décodeur pris en charge et ouvrez-le. Il est supposé que le format d'encodage du. le fichier d’entrée est légal. Ouvrez le fichier de sortie
Utilisezavformat.AvGuessFormat
pour connaître le format d'encodage du fichier de sortie, puis utilisez le avformat.AvformatAllocContext code> pour créer le contexte du fichier de sortie et ouvrir le fichier. 🎜<ol start="4">🎜Lire, décoder et convertir des images audio 🎜🎜🎜Utilisez la fonction <code>avformat.AvReadFrame
pour lire une image du fichier d'entrée et vérifier si elle appartient au flux audio . Si tel est le cas, utilisez un décodeur pour décoder la trame en données audio. Utilisez ensuite la fonction avcodec.AvAudioResample
pour convertir les données audio au taux d'échantillonnage et au format définis. Enfin, utilisez la fonction avformat.AvInterleavedWriteFrame
pour écrire le cadre de sortie dans le fichier de sortie. 🎜🎜🎜Enfin, fermez les fichiers d'entrée et de sortie. 🎜🎜🎜2. Comment utiliser Go pour traiter la vidéo🎜🎜Le traitement des données vidéo en langage Go nécessite également l'utilisation d'une bibliothèque de codecs vidéo, et vous pouvez également utiliser la bibliothèque d'outils ffmpeg. Ensuite, un exemple de code simple pour lire un fichier vidéo, extraire des images et enregistrer est donné : 🎜rrreee🎜Explication du code : 🎜🎜🎜Lire le fichier d'entrée🎜🎜🎜en utilisant également la fonction avformat.AvformatOpenInput
Ouvrir le fichier d'entrée et utilisez avformat.AvformatFindStreamInfo
pour trouver le flux vidéo. 🎜avcodec.AvcodecFindDecoder
dans le code pour trouver le décodeur pris en charge et ouvrez-le. Il est supposé que le format d'encodage de. le fichier d'entrée est légal. 🎜avformat.AvReadFrame
pour lire l'image du fichier d'entrée et vérifier si elle appartient au flux vidéo. Si tel est le cas, utilisez un décodeur pour décoder l'image en données vidéo. Les données vidéo sont ensuite converties en données d'image (ici au format JPEG) via une boucle et écrites dans le fichier de sortie. 🎜🎜🎜Enfin, fermez les fichiers d'entrée et de sortie. 🎜🎜🎜Résumé🎜🎜Cet article présente comment utiliser le langage Go pour traiter les données audio et vidéo. L'analyse, l'encodage et le décodage des formats sont des maillons clés du traitement audio et vidéo. Ici, nous utilisons la bibliothèque d'outils ffmpeg pour traiter les formats audio et vidéo. Dans les applications réelles, des opérations de traitement audio et vidéo plus complexes peuvent être nécessaires, mais le cadre global du code est similaire. Nous espérons que notre exemple de code pourra vous aider pour votre travail de traitement audio et vidéo. 🎜Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!