Maison développement back-end Golang Comment utiliser le langage Go pour le traitement audio et vidéo ?

Comment utiliser le langage Go pour le traitement audio et vidéo ?

Jun 10, 2023 pm 12:07 PM
go语言 音频处理 视频处理

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)
    }
}
Copier après la connexion

Explication du code :

  1. Lire les fichiers d'entrée

Utilisez avformat.AvformatOpenInput ici Le </code > La fonction ouvre le fichier d'entrée et trouve le flux audio à l'aide de <code>avformat.AvformatFindStreamInfo. avformat.AvformatOpenInput 函数打开输入文件,并使用 avformat.AvformatFindStreamInfo 查找音频流。

  1. 打开解码器

在代码中使用 avcodec.AvcodecFindDecoder 函数来查找支持的解码器并打开它,这里假设输入文件的编码格式合法。

  1. 打开输出文件

使用 avformat.AvGuessFormat 找出输出文件的编码格式,然后使用 avformat.AvformatAllocContext 函数创建输出文件上下文并打开文件。

  1. 读取、解码和转换音频帧

使用 avformat.AvReadFrame 函数从输入文件中读取帧,并检查它是否属于音频流。如果是,则使用解码器将帧解码为音频数据。然后再使用 avcodec.AvAudioResample 函数将音频数据转换为设定的采样率和格式。最后,使用 avformat.AvInterleavedWriteFrame 函数将输出帧写入输出文件。

  1. 最后,关闭输入和输出文件。

二、如何使用 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
            }
        }
    }
}
Copier après la connexion

代码解释:

  1. 读取输入文件

同样是使用 avformat.AvformatOpenInput 函数打开输入文件,并使用 avformat.AvformatFindStreamInfo 查找视频流。

  1. 打开解码器

在代码中同样使用 avcodec.AvcodecFindDecoder 函数来查找支持的解码器并打开它,这里假设输入文件的编码格式合法。

  1. 创建输出文件

使用 Go 内置的 os 包创建输出文件并打开。

  1. 提取视频帧

使用 avformat.AvReadFrame

    Ouvrez le décodeur
    1. Utilisez la fonction 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

      Utilisez avformat.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. 🎜
        🎜Ouvrez le décodeur🎜🎜🎜Utilisez également la fonction 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. 🎜
          🎜Créer un fichier de sortie🎜🎜🎜Utilisez le package OS intégré de Go pour créer un fichier de sortie et l'ouvrir. 🎜
            🎜Extraire les images vidéo🎜🎜🎜Utilisez la fonction 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!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Quelles bibliothèques sont utilisées pour les opérations du numéro de point flottantes en Go? Quelles bibliothèques sont utilisées pour les opérations du numéro de point flottantes en Go? Apr 02, 2025 pm 02:06 PM

La bibliothèque utilisée pour le fonctionnement du numéro de point flottante dans le langage go présente comment s'assurer que la précision est ...

Quel est le problème avec le fil de file d'attente dans GO's Crawler Colly? Quel est le problème avec le fil de file d'attente dans GO's Crawler Colly? Apr 02, 2025 pm 02:09 PM

Problème de threading de file d'attente dans Go Crawler Colly explore le problème de l'utilisation de la bibliothèque Crawler Crawler dans le langage Go, les développeurs rencontrent souvent des problèmes avec les threads et les files d'attente de demande. � ...

Quelles bibliothèques de GO sont développées par de grandes entreprises ou fournies par des projets open source bien connus? Quelles bibliothèques de GO sont développées par de grandes entreprises ou fournies par des projets open source bien connus? Apr 02, 2025 pm 04:12 PM

Quelles bibliothèques de GO sont développées par de grandes entreprises ou des projets open source bien connus? Lors de la programmation en Go, les développeurs rencontrent souvent des besoins communs, ...

Quelle est la différence entre la structure de définition des mots clés `var` et« type »dans le langage Go? Quelle est la différence entre la structure de définition des mots clés `var` et« type »dans le langage Go? Apr 02, 2025 pm 12:57 PM

Deux façons de définir les structures dans le langage GO: la différence entre les mots clés VAR et le type. Lorsque vous définissez des structures, GO Language voit souvent deux façons d'écrire différentes: d'abord ...

Dans Go, pourquoi les chaînes d'impression avec println et string () ont-elles des effets différents? Dans Go, pourquoi les chaînes d'impression avec println et string () ont-elles des effets différents? Apr 02, 2025 pm 02:03 PM

La différence entre l'impression de chaîne dans le langage go: la différence dans l'effet de l'utilisation de fonctions println et string () est en Go ...

Que dois-je faire si les étiquettes de structure personnalisées à Goland ne sont pas affichées? Que dois-je faire si les étiquettes de structure personnalisées à Goland ne sont pas affichées? Apr 02, 2025 pm 05:09 PM

Que dois-je faire si les étiquettes de structure personnalisées à Goland ne sont pas affichées? Lorsque vous utilisez Goland pour le développement du langage GO, de nombreux développeurs rencontreront des balises de structure personnalisées ...

Comment résoudre le problème de conversion de type user_id lors de l'utilisation du flux redis pour implémenter les files d'attente de messages dans le langage Go? Comment résoudre le problème de conversion de type user_id lors de l'utilisation du flux redis pour implémenter les files d'attente de messages dans le langage Go? Apr 02, 2025 pm 04:54 PM

Le problème de l'utilisation de Redessstream pour implémenter les files d'attente de messages dans le langage GO consiste à utiliser le langage GO et redis ...

Pourquoi est-il nécessaire de passer des pointeurs lors de l'utilisation de bibliothèques Go et Viper? Pourquoi est-il nécessaire de passer des pointeurs lors de l'utilisation de bibliothèques Go et Viper? Apr 02, 2025 pm 04:00 PM

GO POINTER SYNTAXE ET ATTENDRE DES PROBLÈMES DANS LA BIBLIOTHÈQUE VIPER Lors de la programmation en langage Go, il est crucial de comprendre la syntaxe et l'utilisation des pointeurs, en particulier dans ...

See all articles