分析问题原因
我们在开发时会经常遇到“某个文件未定义”的错误:
如上图所示,我在学习ffmpeg开发的时候,明明是跟着视频一步一步的走的,老师的视频中是很顺利的,而我自己操作的代码,却无论如何都编译不过去。报错如上图所示。
先说一下我ffmpeg的安装步骤;
1、打开 http://ffmpeg.org/download.html
2、直接复制了官网下载首页的克隆git代码的地址,然后进行编译安装了
一切命令行的操作都没有问题。
当使用C语言开发ffmpeg操作文件的时候,出现了问题。
最初的代码如下:
zh@zh-lpc:~/project/ffmpeg$ cat ff.c
#include <stdio.h>
#include <libavutil/log.h>
//#include <libavformat/avio.h>
#include <libavformat/avformat.h>
int main()
{
char *fileName="./test.txt";
int ret;
ret=avpriv_io_delete(fileName);
if(ret < 0)
{
av_log(NULL,AV_LOG_ERROR,"Fail to delete file %s \n",fileName);
return -1;
}
return 0;
}
zh@zh-lpc:~/project/ffmpeg$
编译时遇到:
就在ffmpeg安装目录中查找是否存在包含这个函数的文件:
结果,都没有
zh@zh-lpc:~/project/ffmpeg$ grep -nr "avpriv_io_delete" /usr/local/ffmpeg
zh@zh-lpc:~/project/ffmpeg$
zh@zh-lpc:~/project/ffmpeg$
zh@zh-lpc:~/project/ffmpeg$ cat /usr/local/ffmpeg/include/libavformat/avformat.h |grep "avpriv_io_delete"
zh@zh-lpc:~/project/ffmpeg$
看网友说“avpriv_io_delete”函数在avio.h文件中,就查找了下,结果还是没有:
zh@zh-lpc:~/project/ffmpeg$ cat /usr/local/ffmpeg/include/libavformat/avio.h |grep "avpriv_io_delete"
zh@zh-lpc:~/project/ffmpeg$
很无奈,就猜想是自己编译的代码肯定存在问题的。
想着ffmpeg这么正规,肯定有很详细的api文档,或者其他文档说明。
就在官方查找了一番。
果然看到了API Documentation栏目。
可以查看自己想查看的版本的api。
我就查看了4.1版本的:
http://ffmpeg.org/doxygen/4.1/index.html
在avformat.h文件中查找了一下,也是没有的:
就打开了avio.h文件:
搜索了下,果然相关的函数都存在:
解决办法
既然4.1版本中存在这个函数,那么我只要重新下载4.1版本的代码,然后重新编译安装就行了呗。
这样还是挺麻烦的,因为是git,可以利用切换分支来解决版本的问题。
想切换分支,首先需要找到4.1版本的id是多少。
再次打开官网中的Download界面,然后进入git中的Browse界面中
地址:
https://git.ffmpeg.org/gitweb/ffmpeg.git
直接选择4.1.x的某个版本进入commit中
在此可以看到提交的commit id:
commit 4521700f295f35da4768f88b570e0836a858ce7b
tree 53e22f7d49cc946c635373d32abfa556961067ed
parent 2f54cd9548e2a8fe0ecba9a345b66f0798dd243e
然后进入到自己的ffmpeg的存放目录中,使用如下命令切换分支:
git switch -c 2f54cd9548e2a8fe0ecba9a345b66f0798dd243e
切换后,可以使用git log查看是否切换成功,并当前处在哪个上面:
然后就是重新编译和安装。
可以参考的之前写的:
https://truedei.blog.csdn.net/article/details/120188699
验证
可以看到现在已经有了
zh@zh-lpc:~/project$ cat /usr/local/ffmpeg/include/libavformat/avformat.h |grep "avpriv_io_delete"
zh@zh-lpc:~/project$
zh@zh-lpc:~/project$
zh@zh-lpc:~/project$ cat /usr/local/ffmpeg/include/libavformat/avio.h |grep "avpriv_io_delete"
int avpriv_io_delete(const char *url);
zh@zh-lpc:~/project$
重新编译执行也成功了:
zh@zh-lpc:~/project/ffmpeg$ gcc -g ff.c -o ff -I/usr/local/ffmpeg/include -L/usr/local/ffmpeg/lib -lavformat -lavutil
zh@zh-lpc:~/project/ffmpeg$
zh@zh-lpc:~/project/ffmpeg$
zh@zh-lpc:~/project/ffmpeg$ ls
ff ff.c ffmpeg_file.c hello helloword.c
zh@zh-lpc:~/project/ffmpeg$
zh@zh-lpc:~/project/ffmpeg$ touch test.txt
zh@zh-lpc:~/project/ffmpeg$
zh@zh-lpc:~/project/ffmpeg$ ls
ff ff.c ffmpeg_file.c hello helloword.c test.txt
zh@zh-lpc:~/project/ffmpeg$
zh@zh-lpc:~/project/ffmpeg$ ./ff
zh@zh-lpc:~/project/ffmpeg$
zh@zh-lpc:~/project/ffmpeg$ ls
ff ff.c ffmpeg_file.c hello helloword.c
zh@zh-lpc:~/project/ffmpeg$
测试了一下,头文件写"libavformat/avio.h"和"libavformat/avformat.h"都是可以的:
因为avformat.h中包含了avio.h头文件。
#include <stdio.h>
#include <libavutil/log.h>
//#include <libavformat/avio.h>
#include <libavformat/avformat.h>
int main()
{
char *fileName="./test.txt";
int ret;
ret=avpriv_io_delete(fileName);
if(ret < 0)
{
av_log(NULL,AV_LOG_ERROR,"Fail to delete file %s \n",fileName);
return -1;
}
return 0;
}
~