2023-04-21:用go语言重写ffmpeg的metadata.c示例。

2023-04-21:用go语言重写ffmpeg的metadata.c示例。

答案2023-04-21:

这段 Go 代码演示了如何使用 ffmpeg-go 库中的函数来读取多媒体文件元数据,包括视频、音频等信息。它的大体过程如下:

  1. 设置环境变量以加载 FFmpeg 动态链接库

这里将 FFmpeg 库中的各个动态链接库路径添加到环境变量 PATH 中,以便在程序运行时能够自动加载。同时,通过 ffcommon 包中提供的函数设置各个库的路径。

  1. 创建一个输出目录

如果指定的输出目录不存在,则创建一个新的目录用于存储输出文件。

  1. 打开输入文件并查找流信息

使用 libavformat.AvformatOpenInput() 函数打开用户指定的输入文件,并将返回的 AVFormatContext 结构体指针赋值给 fmt_ctx 变量。然后调用 fmt_ctx.AvformatFindStreamInfo(nil) 函数查找输入文件中的流信息。

  1. 遍历元数据并输出

使用 fmt_ctx.Metadata.AvDictGet() 函数获取输入文件中的元数据。该函数返回指向 AVDictionaryEntry 结构体的指针,其中包含键值对形式的元数据信息。使用 for 循环遍历所有元数据,并使用 fmt.Printf() 函数输出每个元数据的键值对。

  1. 关闭输入文件

使用 libavformat.AvformatCloseInput(&fmt_ctx) 函数关闭输入文件并释放内存。

使用github/moonfdd/ffmpeg-go库。

命令如下:

go run ./examples/internalexamples/metadata/main.go ./resources/big_buck_bunny.mp4

golang代码如下:

package main

import (
    "fmt"
    "os"

    "github.com/moonfdd/ffmpeg-go/ffcommon"
    "github.com/moonfdd/ffmpeg-go/libavformat"
    "github.com/moonfdd/ffmpeg-go/libavutil"
)

func main() {
    // go run ./examples/internalexamples/metadata/main.go ./resources/big_buck_bunny.mp4

    os.Setenv("Path", os.Getenv("Path")+";./lib")
    ffcommon.SetAvutilPath("./lib/avutil-56.dll")
    ffcommon.SetAvcodecPath("./lib/avcodec-58.dll")
    ffcommon.SetAvdevicePath("./lib/avdevice-58.dll")
    ffcommon.SetAvfilterPath("./lib/avfilter-56.dll")
    ffcommon.SetAvformatPath("./lib/avformat-58.dll")
    ffcommon.SetAvpostprocPath("./lib/postproc-55.dll")
    ffcommon.SetAvswresamplePath("./lib/swresample-3.dll")
    ffcommon.SetAvswscalePath("./lib/swscale-5.dll")

    genDir := "./out"
    _, err := os.Stat(genDir)
    if err != nil {
        if os.IsNotExist(err) {
            os.Mkdir(genDir, 0777) //  Everyone can read write and execute
        }
    }
    main0()
}

func main0() (ret ffcommon.FInt) {
    var fmt_ctx *libavformat.AVFormatContext
    var tag *libavutil.AVDictionaryEntry

    if len(os.Args) != 2 {
        fmt.Printf("usage: %s <input_file>\nexample program to demonstrate the use of the libavformat metadata API.\n\n", os.Args[0])
        return 1
    }
    ret = libavformat.AvformatOpenInput(&fmt_ctx, os.Args[1], nil, nil)
    if ret != 0 {
        return ret
    }

    ret = fmt_ctx.AvformatFindStreamInfo(nil)
    if ret < 0 {
        libavutil.AvLog(uintptr(0), libavutil.AV_LOG_ERROR, "Cannot find stream information\n")
        return ret
    }

    tag = fmt_ctx.Metadata.AvDictGet("", tag, libavutil.AV_DICT_IGNORE_SUFFIX)
    for tag != nil {
        fmt.Printf("%s=%s\n", ffcommon.StringFromPtr(tag.Key), ffcommon.StringFromPtr(tag.Value))
        tag = fmt_ctx.Metadata.AvDictGet("", tag, libavutil.AV_DICT_IGNORE_SUFFIX)
    }

    libavformat.AvformatCloseInput(&fmt_ctx)
    return 0
}

在这里插入图片描述

本作品采用《CC 协议》,转载必须注明作者和本文链接
微信公众号:福大大架构师每日一题。最新面试题,涉及golang,rust,mysql,redis,云原生,算法,分布式,网络,操作系统。
讨论数量: 1

「Go 学堂」写了一些列的 gin 框架的底层原理知识。还有相关的使用 go 语言写的开源包系列。欢迎关注

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
486
粉丝
23
喜欢
38
收藏
22
排名:452
访问:2.0 万
私信
所有博文
社区赞助商