2023-03-27:avio_list_dir.c 是 FFmpeg 库自带的一个示例程序,它提供了列出目录中所有文件和子目录的功能,请用go语言改写。
2023-03-27:avio_list_dir.c 是 FFmpeg 库自带的一个示例程序,它提供了列出目录中所有文件和子目录的功能,请用go语言改写。
答案2023-03-27:
这段代码实现了通过 AVIOContext 列出指定目录下的文件和子目录,并打印出它们的名称、大小、类型、权限等信息。
具体流程如下:
1.设置 FFmpeg 库的路径,以及调用 AvformatNetworkInit() 初始化网络相关的组件。
2.调用 AvioOpenDir() 打开指定目录,获取 AVIODirContext 对象。
3.循环调用 AVIODirContext.AvioReadDir() 方法读取目录下的文件和子目录,每次读取到一个目录项后,输出该目录项的信息。如果已经读取完所有目录项,则退出循环。
4.输出格式化的目录项信息,包括类型、大小、名称、权限等。
5.在每次循环中需要调用 AVIODirContext.AvioFreeDirectoryEntry() 方法释放当前目录项所占用的内存空间。
6.最后调用 AvioCloseDir() 关闭目录并销毁 AVIODirContext 对象,调用 AvformatNetworkDeinit() 释放网络相关的资源。
需要注意的是,这段代码只能在支持 AVIOContext 的平台上运行,例如 Linux 上的文件系统或者 S3、HDFS 等云存储服务。而 Windows 平台上不支持 AVIOContext,因此无法使用该方法列出目录下的文件和子目录。
代码见github/moonfdd/ffmpeg-go。
执行命令:
go run ./examples/internalexamples/avio_list_dir/main.go .
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() {
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) {
libavutil.AvLogSetLevel(libavutil.AV_LOG_DEBUG)
if len(os.Args) < 2 {
usage(os.Args[0])
ret = 1
return
}
libavformat.AvformatNetworkInit()
ret = list_op(os.Args[1])
libavformat.AvformatNetworkDeinit()
if ret < 0 {
ret = 1
}
return
}
func type_string(type0 int32) string {
switch type0 {
case libavformat.AVIO_ENTRY_DIRECTORY:
return "<DIR>"
case libavformat.AVIO_ENTRY_FILE:
return "<FILE>"
case libavformat.AVIO_ENTRY_BLOCK_DEVICE:
return "<BLOCK DEVICE>"
case libavformat.AVIO_ENTRY_CHARACTER_DEVICE:
return "<CHARACTER DEVICE>"
case libavformat.AVIO_ENTRY_NAMED_PIPE:
return "<PIPE>"
case libavformat.AVIO_ENTRY_SYMBOLIC_LINK:
return "<LINK>"
case libavformat.AVIO_ENTRY_SOCKET:
return "<SOCKET>"
case libavformat.AVIO_ENTRY_SERVER:
return "<SERVER>"
case libavformat.AVIO_ENTRY_SHARE:
return "<SHARE>"
case libavformat.AVIO_ENTRY_WORKGROUP:
return "<WORKGROUP>"
case libavformat.AVIO_ENTRY_UNKNOWN:
default:
break
}
return "<UNKNOWN>"
}
func list_op(input_dir string) (ret int32) {
var entry *libavformat.AVIODirEntry
var ctx *libavformat.AVIODirContext
var cnt int32
var filemode [4]byte
var uid_and_gid [20]byte
//注意Windows下会返回-40,也就是Function not implement,方法未实现,也就是说windows下不支持此方法
ret = libavformat.AvioOpenDir(&ctx, input_dir, nil)
defer libavformat.AvioCloseDir(&ctx)
if ret < 0 {
libavutil.AvLog(uintptr(0), libavutil.AV_LOG_ERROR, "Cannot open directory: %s.\n", libavutil.AvErr2str(ret))
return
}
cnt = 0
for {
ret = ctx.AvioReadDir(&entry)
if ret < 0 {
libavutil.AvLog(uintptr(0), libavutil.AV_LOG_ERROR, "Cannot list directory: %s.\n", libavutil.AvErr2str(ret))
return
}
if entry == nil {
break
}
if entry.Filemode == -1 {
filemode[0] = '?'
filemode[1] = '?'
filemode[2] = '?'
} else {
f := fmt.Sprint(entry.Filemode)
if len(f) >= 1 {
filemode[0] = f[0]
}
if len(f) >= 2 {
filemode[1] = f[1]
}
if len(f) >= 3 {
filemode[2] = f[2]
}
}
u := fmt.Sprintf("%d%d", entry.UserId, entry.GroupId)
copy(uid_and_gid[0:19], []byte(u))
if cnt == 0 {
libavutil.AvLog(uintptr(0), libavutil.AV_LOG_INFO, "%-9s %12s %30s %10s %s %16s %16s %16s\n",
"TYPE", "SIZE", "NAME", "UID(GID)", "UGO", "MODIFIED",
"ACCESSED", "STATUS_CHANGED")
}
libavutil.AvLog(uintptr(0), libavutil.AV_LOG_INFO, "%-9s %12s %30s %10s %s %16s %16s %16s\n",
type_string(entry.Type),
fmt.Sprint(entry.Size),
ffcommon.StringFromPtr(entry.Name),
string(uid_and_gid[:]),
fmt.Sprint(filemode),
fmt.Sprint(entry.ModificationTimestamp),
fmt.Sprint(entry.AccessTimestamp),
fmt.Sprint(entry.StatusChangeTimestamp))
libavformat.AvioFreeDirectoryEntry(&entry)
cnt++
}
return
}
func usage(program_name string) {
fmt.Printf("usage: %s input_dir\nAPI example program to show how to list files in directory accessed through AVIOContext.\n", program_name)
}

2023-03-27:avio_list_dir.c 是 FFmpeg 库自带的一个示例程序,它提供了列出目录中所有文件和子目录的功能,请用go语言改写。的更多相关文章
- 【VSCode】Windows下VSCode编译调试c/c++【更新 2018.03.27】
--------– 2018.03.27 更新--------- 便携版已更新,点此获取便携版 已知BUG:中文目录无法正常调试 用于cpptools 0.15.0插件的配置文件更新 新的launch ...
- 实战FFmpeg--编译iOS平台使用的FFmpeg库(支持arm64的FFmpeg2.6.2)
编译环境:Mac OS X 10.10.2 ,Xcode 6.3 iOS SDK 8.3 FFmpeg库的下载地址是 http://www.ffmpeg.org/releases/ . ...
- FFmpeg示例程序合集-批量编译脚本
此前做了一系列有关FFmpeg的示例程序,组成了<最简单的FFmpeg示例程序合集>,其中包含了如下项目:simplest ffmpeg player: ...
- 背水一战 Windows 10 (90) - 文件系统: 获取 Package 中的文件, 可移动存储中的文件操作, “库”管理
[源码下载] 背水一战 Windows 10 (90) - 文件系统: 获取 Package 中的文件, 可移动存储中的文件操作, “库”管理 作者:webabcd 介绍背水一战 Windows 10 ...
- Android APP使用NDK编译后的ffmpeg库出现undefined reference to 'posix_memalign'错误
在android程序中使用NDK编译后的ffmpeg库的时候出现了如下错误: jni/libs/libavutil.a(mem.o): in function av_malloc:libavutil/ ...
- 【转】FFMPEG 库移植到 VC 需要的步骤
原文:http://blog.csdn.net/leixiaohua1020/article/details/12747899 在VC下使用FFMPEG编译好的库,不仅仅是把.h,.lib,.dll拷 ...
- FFMPEG 库移植到 VC 需要的步骤
在VC下使用FFMPEG编译好的库,不仅仅是把.h,.lib,.dll拷贝到工程中就行了,还需要做以下几步.(此方法适用于自己使用MinGW编译的库,也同样适用于从网上下载的编译好的库,例如http: ...
- 【UWP】FFmpeg库的编译
本文是关于windows8.1/windows10通用应用下编译ffmpeg的一些需要注意的地方,针对最新的msys2而写,都是我在实际操作中遇到的,但是网上没有提到的.如果大家遇到什么问题或是在之前 ...
- IOS应用FFMPEG库
1.引用资源 build-ffmpeg ffmpeg库生成 -sh开源地址: https://gist.github.com/m1entus/6983547 iFrameExtractor ffmp ...
- 手把手图文并茂教你用Android Studio编译FFmpeg库并移植
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52661331 之前曾写过一篇&l ...
随机推荐
- PHP 计算一个月第一天和最后一天
$fistday= date('Y-m-1 23:59:59'); $lastday= strtotime("$fistday+1 month -1 day");
- 函数XLOOKUP
这个公式非OFFICE 365用户需要选中执行范围后 按Ctrl+Shift+Enter三键 (因为不支持公式溢出) XLOOKUP函数的基本结构是: =XLOOKUP(lookup_value,lo ...
- DVWA-File Upload(文件上传)
文件上传是很危险的漏洞,攻击者上传木马到服务器,可以获取服务器的操作权限 LOW 审计源码 <?php if( isset( $_POST[ 'Upload' ] ) ) { // 定义 文件上 ...
- java生态下的后端开发都有哪些技术栈?
前言 我08年毕业,那时(2003-2010)C#还比较时髦的,大学跟着老师进修的,毕业后就从事winform窗体应用程序开发.慢慢的web网站兴起,就转到aps.net开发,再到后来就上了另一艘船( ...
- Python--基本知识认知及应用
字面量 概念:被写下来的固定的值(既包括print里面的值,也包括直接写到编程页面的值) 在Python中,常用的有六种值的类型:数字.字符串.列表.元组.集合以及字典: Python中,被双引号包围 ...
- 面向对象分析与设计(V3)第一章:复杂性
书名(中):面向对象分析与设计 书名(英):Object-Oriented Analysis and Design with Applications 作者:Grady Booch等 第一部分.概念 ...
- (数据科学学习手札150)基于dask对geopandas进行并行加速
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 大家好我是费老师,geopandas作为我们非常 ...
- Yaml入门与使用
一.入门 1.概念: yml是YAML("YAML Ain't a Markup Language)语言文件,以数据为中心,而不是一标记语言为重点,比json,xml更适合做配置文件. 为 ...
- markdown---->Typora搭配uPic
记录一下在mac上面使用Typora和uPic来发表博客的过程,图床用的是阿里Oss.We all, whether we know it or not, are fighting to make t ...
- Go语言:编写一个 WebsiteRacer 的函数,用来对比请求两个 URL 来「比赛」,并返回先响应的 URL。如果两个 URL 在 10 秒内都未返回结果,返回一个 error。
问题: 你被要求编写一个叫做 WebsiteRacer 的函数,用来对比请求两个 URL 来「比赛」,并返回先响应的 URL.如果两个 URL 在 10 秒内都未返回结果,那么应该返回一个 error ...