最简单的基于FFmpeg的AVDevice例子(读取摄像头)【转】

转自:http://blog.csdn.net/leixiaohua1020/article/details/39702113

版权声明:本文为博主原创文章,未经博主允许不得转载。

目录(?)[-]

  1. libavdevice使用
    1. 注意事项
  2. 代码
  3. 结果
  4. 下载

=====================================================
最简单的基于FFmpeg的AVDevice例子文章列表:

最简单的基于FFmpeg的AVDevice例子(读取摄像头)

最简单的基于FFmpeg的AVDevice例子(屏幕录制)
=====================================================

FFmpeg中有一个和多媒体设备交互的类库:Libavdevice。使用这个库可以读取电脑(或者其他设备上)的多媒体设备的数据,或者输出数据到指定的多媒体设备上。

Libavdevice支持以下设备作为输入端:

alsa
avfoundation
bktr
dshow
dv1394
fbdev
gdigrab
iec61883
jack
lavfi
libcdio
libdc1394
openal
oss
pulse
qtkit
sndio
video4linux2, v4l2
vfwcap
x11grab
decklink

Libavdevice支持以下设备作为输出端:

alsa
caca
decklink
fbdev
opengl
oss
pulse
sdl
sndio
xv

libavdevice使用

计划记录两个基于FFmpeg的libavdevice类库的例子,分成两篇文章写。本文记录一个基于FFmpeg的Libavdevice类库读取摄像头数据的例子。下一篇文章记录一个基于FFmpeg的Libavdevice类库录制屏幕的例子。本文程序读取计算机上的摄像头的数据并且解码显示出来。有关解码显示方面的代码本文不再详述,可以参考文章:
100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)

本文主要记录使用libavdevice需要注意的步骤。

首先,使用libavdevice的时候需要包含其头文件:

[cpp] view plain copy

  1. #include "libavdevice/avdevice.h"

然后,在程序中需要注册libavdevice:

[cpp] view plain copy

  1. avdevice_register_all();

接下来就可以使用libavdevice的功能了。
使用libavdevice读取数据和直接打开视频文件比较类似。因为系统的设备也被FFmpeg认为是一种输入的格式(即AVInputFormat)。使用FFmpeg打开一个普通的视频文件使用如下函数:

[cpp] view plain copy

  1. AVFormatContext *pFormatCtx = avformat_alloc_context();
  2. avformat_open_input(&pFormatCtx, "test.h265",NULL,NULL);

使用libavdevice的时候,唯一的不同在于需要首先查找用于输入的设备。在这里使用av_find_input_format()完成:

[cpp] view plain copy

  1. AVFormatContext *pFormatCtx = avformat_alloc_context();
  2. AVInputFormat *ifmt=av_find_input_format("vfwcap");
  3. avformat_open_input(&pFormatCtx, 0, ifmt,NULL);

上述代码首先指定了vfw设备作为输入设备,然后在URL中指定打开第0个设备(在我自己计算机上即是摄像头设备)。
在Windows平台上除了使用vfw设备作为输入设备之外,还可以使用DirectShow作为输入设备:

[cpp] view plain copy

  1. AVFormatContext *pFormatCtx = avformat_alloc_context();
  2. AVInputFormat *ifmt=av_find_input_format("dshow");
  3. avformat_open_input(&pFormatCtx,"video=Integrated Camera",ifmt,NULL) ;

使用ffmpeg.exe打开vfw设备和Directshow设备的方法可以参考文章:
FFmpeg获取DirectShow设备数据(摄像头,录屏)

注意事项

1. URL的格式是"video={设备名称}",但是设备名称外面不能加引号。例如在上述例子中URL是"video=Integrated Camera",而不能写成"video=\"Integrated Camera\"",否则就无法打开设备。这与直接使用ffmpeg.exe打开dshow设备(命令为:ffmpeg -list_options true -f dshow -i video="Integrated Camera")有很大的不同。
2. Dshow的设备名称必须要提前获取,在这里有两种方法:

(1) 通过FFmpeg编程实现。使用如下代码:

[cpp] view plain copy

  1. //Show Device
  2. void show_dshow_device(){
  3. AVFormatContext *pFormatCtx = avformat_alloc_context();
  4. AVDictionary* options = NULL;
  5. av_dict_set(&options,"list_devices","true",0);
  6. AVInputFormat *iformat = av_find_input_format("dshow");
  7. printf("Device Info=============\n");
  8. avformat_open_input(&pFormatCtx,"video=dummy",iformat,&options);
  9. printf("========================\n");
  10. }

上述代码实际上相当于输入了下面一条命令:

[plain] view plain copy

  1. ffmpeg -list_devices true -f dshow -i dummy

执行的结果如下图所示:

该方法好处是可以使用程序自动获取名称。但是当设备名称中包含中文字符的时候,会出现设备名称为乱码的情况。如果直接把乱码的设备名作为输入的话,是无法打开该设备的。这时候需要把乱码ANSI转换为UTF-8。例如上图中的第一个音频设备显示为“鍐呰楹﹀厠椋?(Conexant 20672 SmartAudi”,转码之后即为“内装麦克风 (Conexant 20672 SmartAudi”。使用转码之后的名称即可打开该设备。

(2) 自己去系统中看。
这个方法更简单一些,但是缺点是需要手工操作。该方法使用DirectShow的调试工具GraphEdit(或者网上下一个GraphStudioNext)即可查看输入名称。
打开GraphEdit选择“图像->插入滤镜”

然后就可以通过查看Audio Capture Sources来查看音频输入设备的简体中文名称了。从图中可以看出是“内装麦克风 (Conexant 20672 SmartAudi”。

在Linux平台上可以使用video4linux2打开视频设备;在MacOS上,可以使用avfoundation打开视频设备,这里不再详述。

代码

下面直接贴上程序代码:

[cpp] view plain copy

  1. /**
  2. * 最简单的基于FFmpeg的AVDevice例子(读取摄像头)
  3. * Simplest FFmpeg Device (Read Camera)
  4. *
  5. * 雷霄骅 Lei Xiaohua
  6. * [email protected]
  7. * 中国传媒大学/数字电视技术
  8. * Communication University of China / Digital TV Technology
  9. * http://blog.csdn.net/leixiaohua1020
  10. *
  11. * 本程序实现了本地摄像头数据的获取解码和显示。是基于FFmpeg
  12. * 的libavdevice类库最简单的例子。通过该例子,可以学习FFmpeg中
  13. * libavdevice类库的使用方法。
  14. * 本程序在Windows下可以使用2种方式读取摄像头数据:
  15. *  1.VFW: Video for Windows 屏幕捕捉设备。注意输入URL是设备的序号,
  16. *          从0至9。
  17. *  2.dshow: 使用Directshow。注意作者机器上的摄像头设备名称是
  18. *         “Integrated Camera”,使用的时候需要改成自己电脑上摄像头设
  19. *          备的名称。
  20. * 在Linux下可以使用video4linux2读取摄像头设备。
  21. * 在MacOS下可以使用avfoundation读取摄像头设备。
  22. *
  23. * This software read data from Computer‘s Camera and play it.
  24. * It‘s the simplest example about usage of FFmpeg‘s libavdevice Library.
  25. * It‘s suiltable for the beginner of FFmpeg.
  26. * This software support 2 methods to read camera in Microsoft Windows:
  27. *  1.gdigrab: VfW (Video for Windows) capture input device.
  28. *             The filename passed as input is the capture driver number,
  29. *             ranging from 0 to 9.
  30. *  2.dshow: Use Directshow. Camera‘s name in author‘s computer is
  31. *             "Integrated Camera".
  32. * It use video4linux2 to read Camera in Linux.
  33. * It use avfoundation to read Camera in MacOS.
  34. *
  35. */
  36. #include <stdio.h>
  37. #define __STDC_CONSTANT_MACROS
  38. #ifdef _WIN32
  39. //Windows
  40. extern "C"
  41. {
  42. #include "libavcodec/avcodec.h"
  43. #include "libavformat/avformat.h"
  44. #include "libswscale/swscale.h"
  45. #include "libavdevice/avdevice.h"
  46. #include "SDL/SDL.h"
  47. };
  48. #else
  49. //Linux...
  50. #ifdef __cplusplus
  51. extern "C"
  52. {
  53. #endif
  54. #include <libavcodec/avcodec.h>
  55. #include <libavformat/avformat.h>
  56. #include <libswscale/swscale.h>
  57. #include <libavdevice/avdevice.h>
  58. #include <SDL/SDL.h>
  59. #ifdef __cplusplus
  60. };
  61. #endif
  62. #endif
  63. //Output YUV420P
  64. #define OUTPUT_YUV420P 0
  65. //‘1‘ Use Dshow
  66. //‘0‘ Use VFW
  67. #define USE_DSHOW 0
  68. //Refresh Event
  69. #define SFM_REFRESH_EVENT  (SDL_USEREVENT + 1)
  70. #define SFM_BREAK_EVENT  (SDL_USEREVENT + 2)
  71. int thread_exit=0;
  72. int sfp_refresh_thread(void *opaque)
  73. {
  74. thread_exit=0;
  75. while (!thread_exit) {
  76. SDL_Event event;
  77. event.type = SFM_REFRESH_EVENT;
  78. SDL_PushEvent(&event);
  79. SDL_Delay(40);
  80. }
  81. thread_exit=0;
  82. //Break
  83. SDL_Event event;
  84. event.type = SFM_BREAK_EVENT;
  85. SDL_PushEvent(&event);
  86. return 0;
  87. }
  88. //Show Dshow Device
  89. void show_dshow_device(){
  90. AVFormatContext *pFormatCtx = avformat_alloc_context();
  91. AVDictionary* options = NULL;
  92. av_dict_set(&options,"list_devices","true",0);
  93. AVInputFormat *iformat = av_find_input_format("dshow");
  94. printf("========Device Info=============\n");
  95. avformat_open_input(&pFormatCtx,"video=dummy",iformat,&options);
  96. printf("================================\n");
  97. }
  98. //Show Dshow Device Option
  99. void show_dshow_device_option(){
  100. AVFormatContext *pFormatCtx = avformat_alloc_context();
  101. AVDictionary* options = NULL;
  102. av_dict_set(&options,"list_options","true",0);
  103. AVInputFormat *iformat = av_find_input_format("dshow");
  104. printf("========Device Option Info======\n");
  105. avformat_open_input(&pFormatCtx,"video=Integrated Camera",iformat,&options);
  106. printf("================================\n");
  107. }
  108. //Show VFW Device
  109. void show_vfw_device(){
  110. AVFormatContext *pFormatCtx = avformat_alloc_context();
  111. AVInputFormat *iformat = av_find_input_format("vfwcap");
  112. printf("========VFW Device Info======\n");
  113. avformat_open_input(&pFormatCtx,"list",iformat,NULL);
  114. printf("=============================\n");
  115. }
  116. //Show AVFoundation Device
  117. void show_avfoundation_device(){
  118. AVFormatContext *pFormatCtx = avformat_alloc_context();
  119. AVDictionary* options = NULL;
  120. av_dict_set(&options,"list_devices","true",0);
  121. AVInputFormat *iformat = av_find_input_format("avfoundation");
  122. printf("==AVFoundation Device Info===\n");
  123. avformat_open_input(&pFormatCtx,"",iformat,&options);
  124. printf("=============================\n");
  125. }
  126. int main(int argc, char* argv[])
  127. {
  128. AVFormatContext *pFormatCtx;
  129. int             i, videoindex;
  130. AVCodecContext  *pCodecCtx;
  131. AVCodec         *pCodec;
  132. av_register_all();
  133. avformat_network_init();
  134. pFormatCtx = avformat_alloc_context();
  135. //Open File
  136. //char filepath[]="src01_480x272_22.h265";
  137. //avformat_open_input(&pFormatCtx,filepath,NULL,NULL)
  138. //Register Device
  139. avdevice_register_all();
  140. //Windows
  141. #ifdef _WIN32
  142. //Show Dshow Device
  143. show_dshow_device();
  144. //Show Device Options
  145. show_dshow_device_option();
  146. //Show VFW Options
  147. show_vfw_device();
  148. #if USE_DSHOW
  149. AVInputFormat *ifmt=av_find_input_format("dshow");
  150. //Set own video device‘s name
  151. if(avformat_open_input(&pFormatCtx,"video=Integrated Camera",ifmt,NULL)!=0){
  152. printf("Couldn‘t open input stream.\n");
  153. return -1;
  154. }
  155. #else
  156. AVInputFormat *ifmt=av_find_input_format("vfwcap");
  157. if(avformat_open_input(&pFormatCtx,"0",ifmt,NULL)!=0){
  158. printf("Couldn‘t open input stream.\n");
  159. return -1;
  160. }
  161. #endif
  162. #elif defined linux
  163. //Linux
  164. AVInputFormat *ifmt=av_find_input_format("video4linux2");
  165. if(avformat_open_input(&pFormatCtx,"/dev/video0",ifmt,NULL)!=0){
  166. printf("Couldn‘t open input stream.\n");
  167. return -1;
  168. }
  169. #else
  170. show_avfoundation_device();
  171. //Mac
  172. AVInputFormat *ifmt=av_find_input_format("avfoundation");
  173. //Avfoundation
  174. //[video]:[audio]
  175. if(avformat_open_input(&pFormatCtx,"0",ifmt,NULL)!=0){
  176. printf("Couldn‘t open input stream.\n");
  177. return -1;
  178. }
  179. #endif
  180. if(avformat_find_stream_info(pFormatCtx,NULL)<0)
  181. {
  182. printf("Couldn‘t find stream information.\n");
  183. return -1;
  184. }
  185. videoindex=-1;
  186. for(i=0; i<pFormatCtx->nb_streams; i++)
  187. if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
  188. {
  189. videoindex=i;
  190. break;
  191. }
  192. if(videoindex==-1)
  193. {
  194. printf("Couldn‘t find a video stream.\n");
  195. return -1;
  196. }
  197. pCodecCtx=pFormatCtx->streams[videoindex]->codec;
  198. pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
  199. if(pCodec==NULL)
  200. {
  201. printf("Codec not found.\n");
  202. return -1;
  203. }
  204. if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
  205. {
  206. printf("Could not open codec.\n");
  207. return -1;
  208. }
  209. AVFrame *pFrame,*pFrameYUV;
  210. pFrame=av_frame_alloc();
  211. pFrameYUV=av_frame_alloc();
  212. //unsigned char *out_buffer=(unsigned char *)av_malloc(avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));
  213. //avpicture_fill((AVPicture *)pFrameYUV, out_buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
  214. //SDL----------------------------
  215. if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
  216. printf( "Could not initialize SDL - %s\n", SDL_GetError());
  217. return -1;
  218. }
  219. int screen_w=0,screen_h=0;
  220. SDL_Surface *screen;
  221. screen_w = pCodecCtx->width;
  222. screen_h = pCodecCtx->height;
  223. screen = SDL_SetVideoMode(screen_w, screen_h, 0,0);
  224. if(!screen) {
  225. printf("SDL: could not set video mode - exiting:%s\n",SDL_GetError());
  226. return -1;
  227. }
  228. SDL_Overlay *bmp;
  229. bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height,SDL_YV12_OVERLAY, screen);
  230. SDL_Rect rect;
  231. rect.x = 0;
  232. rect.y = 0;
  233. rect.w = screen_w;
  234. rect.h = screen_h;
  235. //SDL End------------------------
  236. int ret, got_picture;
  237. AVPacket *packet=(AVPacket *)av_malloc(sizeof(AVPacket));
  238. #if OUTPUT_YUV420P
  239. FILE *fp_yuv=fopen("output.yuv","wb+");
  240. #endif
  241. struct SwsContext *img_convert_ctx;
  242. img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
  243. //------------------------------
  244. SDL_Thread *video_tid = SDL_CreateThread(sfp_refresh_thread,NULL);
  245. //
  246. SDL_WM_SetCaption("Simplest FFmpeg Read Camera",NULL);
  247. //Event Loop
  248. SDL_Event event;
  249. for (;;) {
  250. //Wait
  251. SDL_WaitEvent(&event);
  252. if(event.type==SFM_REFRESH_EVENT){
  253. //------------------------------
  254. if(av_read_frame(pFormatCtx, packet)>=0){
  255. if(packet->stream_index==videoindex){
  256. ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
  257. if(ret < 0){
  258. printf("Decode Error.\n");
  259. return -1;
  260. }
  261. if(got_picture){
  262. SDL_LockYUVOverlay(bmp);
  263. pFrameYUV->data[0]=bmp->pixels[0];
  264. pFrameYUV->data[1]=bmp->pixels[2];
  265. pFrameYUV->data[2]=bmp->pixels[1];
  266. pFrameYUV->linesize[0]=bmp->pitches[0];
  267. pFrameYUV->linesize[1]=bmp->pitches[2];
  268. pFrameYUV->linesize[2]=bmp->pitches[1];
  269. sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
  270. #if OUTPUT_YUV420P
  271. int y_size=pCodecCtx->width*pCodecCtx->height;
  272. fwrite(pFrameYUV->data[0],1,y_size,fp_yuv);    //Y
  273. fwrite(pFrameYUV->data[1],1,y_size/4,fp_yuv);  //U
  274. fwrite(pFrameYUV->data[2],1,y_size/4,fp_yuv);  //V
  275. #endif
  276. SDL_UnlockYUVOverlay(bmp);
  277. SDL_DisplayYUVOverlay(bmp, &rect);
  278. }
  279. }
  280. av_free_packet(packet);
  281. }else{
  282. //Exit Thread
  283. thread_exit=1;
  284. }
  285. }else if(event.type==SDL_QUIT){
  286. thread_exit=1;
  287. }else if(event.type==SFM_BREAK_EVENT){
  288. break;
  289. }
  290. }
  291. sws_freeContext(img_convert_ctx);
  292. #if OUTPUT_YUV420P
  293. fclose(fp_yuv);
  294. #endif
  295. SDL_Quit();
  296. //av_free(out_buffer);
  297. av_free(pFrameYUV);
  298. avcodec_close(pCodecCtx);
  299. avformat_close_input(&pFormatCtx);
  300. return 0;
  301. }

结果

程序的运行效果如下。输出了摄像头的数据。

可以通过下面的宏定义来确定是否将解码后的YUV420P数据输出成文件:

[cpp] view plain copy

  1. #define OUTPUT_YUV420P 0

可以通过下面的宏定义来确定使用VFW或者是Dshow打开摄像头:

[cpp] view plain copy

  1. //‘1‘ Use Dshow
  2. //‘0‘ Use VFW
  3. #define USE_DSHOW 0

下载

 

Simplest FFmpeg Device 

项目主页

SourceForge:https://sourceforge.net/projects/simplestffmpegdevice/

Github:https://github.com/leixiaohua1020/simplest_ffmpeg_device

开源中国:http://git.oschina.net/leixiaohua1020/simplest_ffmpeg_device

CSDN下载地址:

http://download.csdn.net/detail/leixiaohua1020/7994049

注:

本工程包含两个基于FFmpeg的libavdevice的例子:
 simplest_ffmpeg_grabdesktop:屏幕录制。
 simplest_ffmpeg_readcamera:读取摄像头。

更新-1.1(2015.1.9)=========================================

该版本中,修改了SDL的显示方式,弹出的窗口可以移动了。

CSDN下载地址:http://download.csdn.net/detail/leixiaohua1020/8344695

更新-1.2 (2015.2.13)=========================================

这次考虑到了跨平台的要求,调整了源代码。经过这次调整之后,源代码可以在以下平台编译通过:

VC++:打开sln文件即可编译,无需配置。

cl.exe:打开compile_cl.bat即可命令行下使用cl.exe进行编译,注意可能需要按照VC的安装路径调整脚本里面的参数。编译命令如下。

[plain] view plain copy

  1. ::VS2010 Environment
  2. call "D:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
  3. ::include
  4. @set INCLUDE=include;%INCLUDE%
  5. ::lib
  6. @set LIB=lib;%LIB%
  7. ::compile and link
  8. cl simplest_ffmpeg_readcamera.cpp /MD /link SDL.lib SDLmain.lib avcodec.lib ^
  9. avformat.lib avutil.lib avdevice.lib avfilter.lib postproc.lib swresample.lib swscale.lib ^
  10. /SUBSYSTEM:WINDOWS /OPT:NOREF

MinGW:MinGW命令行下运行compile_mingw.sh即可使用MinGW的g++进行编译。编译命令如下。

[plain] view plain copy

  1. g++ simplest_ffmpeg_readcamera.cpp -g -o simplest_ffmpeg_readcamera.exe \
  2. -I /usr/local/include -L /usr/local/lib \
  3. -lmingw32 -lSDLmain -lSDL -lavformat -lavcodec -lavutil -lavdevice -lswscale

GCC(Linux):Linux命令行下运行compile_gcc.sh即可使用GCC进行编译。编译命令如下。

[plain] view plain copy

  1. gcc simplest_ffmpeg_readcamera.cpp -g -o simplest_ffmpeg_readcamera.out \
  2. -I /usr/local/include -L /usr/local/lib -lSDLmain -lSDL -lavformat -lavcodec -lavutil -lavdevice -lswscale

GCC(MacOS):MacOS命令行下运行compile_gcc_mac.sh即可使用GCC进行编译。Mac的GCC和Linux的GCC差别不大,但是使用SDL1.2的时候,必须加上“-framework Cocoa”参数,否则编译无法通过。编译命令如下。

[plain] view plain copy

  1. gcc simplest_ffmpeg_readcamera.cpp -g -o simplest_ffmpeg_readcamera.out \
  2. -framework Cocoa -I /usr/local/include -L /usr/local/lib -lSDLmain -lSDL -lavformat -lavcodec -lavutil -lavdevice -lswscale

PS:相关的编译命令已经保存到了工程文件夹中

此外,增加了MacOS下使用avfoundation读取摄像头的代码。

CSDN下载地址:http://download.csdn.net/detail/leixiaohua1020/8445747

SourceForge上已经更新。

时间: 2024-10-06 00:31:06

最简单的基于FFmpeg的AVDevice例子(读取摄像头)【转】的相关文章

最简单的基于FFmpeg的AVDevice例子(读取摄像头)

FFmpeg中有一个和多媒体设备交互的类库:Libavdevice.使用这个库可以读取电脑(或者其他设备上)的多媒体设备的数据,或者输出数据到指定的多媒体设备上.Libavdevice支持以下设备作为输入端: alsaavfoundationbktrdshowdv1394fbdevgdigrabiec61883jacklavfilibcdiolibdc1394openalosspulseqtkitsndiovideo4linux2, v4l2vfwcapx11grabdecklink Libav

最简单的基于FFmpeg的AVDevice例子(屏幕录制)

??FFmpeg中有一个和多媒体设备交互的类库:Libavdevice.使用这个库可以读取电脑的多媒体设备的数据,或者输出数据到指定的多媒体设备上. 计划写2个有关FFmpeg的libavdevice类库的例子.上篇文章记录了一个基于FFmpeg的Libavdevice类库读取摄像头数据的例子.本篇文章记录一个基于FFmpeg的Libavdevice类库录制屏幕的例子.本文程序录制当前桌面内容并且解码显示出来.有关解码显示方面的代码本文不再详述,可以参考文章:<100行代码实现最简单的基于FFM

最简单的基于FFmpeg的AVfilter例子(水印叠加)

FFMPEG中有一个类库:libavfilter.该类库提供了各种视音频过滤器.之前一直没有怎么使用过这个类库,最近看了一下它的使用说明,发现还是很强大的,有很多现成的filter供使用,完成视频的处理很方便.在此将它的一个例子基础上完成了一个水印叠加器,并且移植到了VC2010下,方便开发人员学习研究它的使用方法. 该例子完成了一个水印叠加的功能.可以将一张透明背景的PNG图片作为水印叠加到一个视频文件上. 下面直接贴上代码: /* * 最简单的基于FFmpeg的AVFilter例子(叠加水印

转: 最简单的基于FFmpeg的AVfilter例子(水印叠加)

该例子完成了一个水印叠加的功能.可以将一张透明背景的PNG图片作为水印叠加到一个视频文件上. 1. [代码][C/C++]代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65

最简单的基于FFmpeg的AVDevice样例(读取摄像头)

=====================================================最简单的基于FFmpeg的AVDevice样例文章列表: 最简单的基于FFmpeg的AVDevice样例(读取摄像头) 最简单的基于FFmpeg的AVDevice样例(屏幕录制)===================================================== FFmpeg中有一个和多媒体设备交互的类库:Libavdevice. 使用这个库能够读取电脑(或者其它设备上

最简单的基于FFmpeg的AVUtil例子 (AVLog, AVOption等)

本文的示例程序记录了FFmpeg的libavutil中几种工具函数的使用方法: AVLog:日志输出AVOption (AVClass):选项设置AVDictionary:键值对存储ParseUtil:字符串解析 几个libavutil的工具 AVLog AVLog是FFmpeg的日志输出工具.在FFmpeg中所有的日志输出不是通过printf()函数而是通过av_log()函数.av_log()会最终调用fprintf(stderr,-)函数将日志内容输出到命令行界面上.但是在一些非命令行程序

最简单的基于FFmpeg的移动端例子:Android HelloWorld

从本文开始打算记录一系列FFmpeg在Android/IOS开发的示例程序.前面几篇文章记录FFmpeg安卓端开发的例子,后面几篇文章记录FFmpeg IOS端开发的例子.这些例子中FFmpeg相关的代码源自于<FFmpeg示例合集>中的程序.本文记录第一个程序:安卓平台下基于FFmpeg的HelloWorld程序. Android程序FFmpeg类库使用说明 Android应用程序使用FFmpeg类库的流程图如下所示. 上图中的流程可以分为"编译FFmpeg类库".&qu

最简单的基于FFmpeg的AVfilter的例子-纯净版

===================================================== 最简单的基于FFmpeg的AVfilter例子系列文章: 最简单的基于FFmpeg的AVfilter例子(水印叠加) 最简单的基于FFmpeg的AVfilter的例子-纯净版 ===================================================== 有关FFmpeg的avfilter已经写过一个水印叠加的例子<最简单的基于FFmpeg的AVfilter例子

最简单的基于FFMPEG的转码程序 [转]

本文介绍一个简单的基于FFmpeg的转码器.它可以将一种视频格式(包括封转格式和编码格式)转换为另一种视频格式.转码器在视音频编解码处理的 程序中,属于一个比较复杂的东西.因为它结合了视频的解码和编码.一个视频播放器,一般只包含解码功能:一个视频编码工具,一般只包含编码功能:而一个视 频转码器,则需要先对视频进行解码,然后再对视频进行编码,因而相当于解码器和编码器的结合.下图例举了一个视频的转码流程.输入视频的封装格式是 FLV,视频编码标准是H.264,音频编码标准是AAC:输出视频的封装格式