找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3952|回复: 1

【DirectShow】视频内置播放器Video Internal Player

[复制链接]

1111

主题

1651

回帖

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
244
威望
743 点
宅币
24237 个
贡献
46222 次
宅之契约
0 份
在线时间
2297 小时
注册时间
2014-1-26
发表于 2014-10-3 06:26:50 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
这个视频内置播放器的作用,是用来将视频实时渲染成位图的图像并放到内存,以用作其它用途,比如做成OpenGL或DirectX的动态纹理、做成视频播放器、将视频图像一帧一帧生成BMP、搞成网络播放视频的工具等。

我这个东西的用法很简单。包含VIP.H,建立VIP结构体,然后调用InitVIP,这个函数可以设定你要播放视频的文件位置,以及你接收视频图像数据的方式。
有两种方式,一种方式是VIP自动帮你把图像数据拷贝到你给的缓冲区,另一种方式则是每次渲染完就调用你给的回调函数,然后你就可以自己去取图像数据了。

用户只需要VIP.H和VIPConf.h还有<streams.h>。
其中<streams.h>是DirectShow的头文件,来自BaseClasses
  1. //=============================================================================
  2. //VIP.H:
  3. //Video Internal Player
  4. //在Windows下借助DirectShow将视频文件播放到内部缓冲区,以用作其它用途。
  5. //
  6. //有两种用法:
  7. //1、在FnOnGetInfo回调函数里,指定pWriteTo指向一个缓冲区。然后VIP每次渲染时都会
  8. //   将图像数据写入这个缓冲区。
  9. //2、直接在FnOnRender回调函数里从pBits参数读取位图数据。
  10. //
  11. //第一种方法略慢(因为拷贝了一次缓冲区数据),但是不容易出错。
  12. //第二种方法省去了一次拷贝操作,但是因为框架变动,容易出现错误。
  13. //(VB不能用第二种方法)
  14. //
  15. //作者:0xAA55
  16. //论坛:http://www.0xaa55.com/
  17. //版权所有 (C) 2013-2014 技术宅的结界
  18. //请保留原作者信息,否则视为侵权。
  19. //-----------------------------------------------------------------------------

  20. #ifndef _VIDEO_INTERNAL_PLAYER_
  21. #define        _VIDEO_INTERNAL_PLAYER_

  22. #include"VIPConf.h"
  23. #include<streams.h>

  24. //=============================================================================
  25. //载入视频文件时取得参数时调用的回调函数
  26. //
  27. //用户可以在回调函数里通过给(*ppWriteTo)赋值来指定VIP的图像缓冲区。
  28. //当(*ppWriteTo)==NULL的时候,VIP不会将图像数据写入任何缓冲区。
  29. //-----------------------------------------------------------------------------
  30. typedef void(VIPCallbackP FnOnGetInfo)
  31. (
  32.         size_t Width,//视频宽度
  33.         size_t Height,//视频高度
  34.         size_t Pitch,//视频每行字节数
  35.         void**ppWriteTo,//用户指定要写入图像数据的缓冲区
  36.         void*pUserData//用户的自定义信息
  37. );

  38. //=============================================================================
  39. //解码器完成一帧渲染时调用的回调函数
  40. //-----------------------------------------------------------------------------
  41. typedef void(VIPCallbackP FnOnRender)
  42. (
  43.         size_t Width,//视频宽度
  44.         size_t Height,//视频高度
  45.         size_t Pitch,//视频每行字节数
  46.         void*pBits,//图像数据
  47.         void*pUserData
  48. );

  49. //=============================================================================
  50. //VIP的结构体。
  51. //-----------------------------------------------------------------------------
  52. typedef struct
  53. {
  54.         IGraphBuilder        *m_pGB;                        //图表构建器
  55.         IMediaControl        *m_pMC;                        //多媒体控制
  56.         IMediaPosition        *m_pMP;                        //多媒体播放位置
  57.         IMediaEvent                *m_pME;                        //多媒体事件
  58.         IBaseFilter                *m_pRenderer;        //渲染器
  59.         void                        *pUserData;                //用户自定义信息
  60. }VIP,*VIPP;

  61. //=============================================================================
  62. //InitVIP;
  63. //初始化VIP。返回一个HRESULT
  64. //
  65. //其中FnOnGetInfo和FnOnRender都可以为NULL。
  66. //加载视频的时候,FnOnGetInfo会被调用。视频解码器每渲染一帧,FnOnRender会被调用
  67. //一次。而如果FnOnGetInfo在调用的时候(*ppWriteTo)被改写,则每渲染一帧,VIP都会
  68. //将图像数据复制到(*ppWriteTo)
  69. //
  70. //找不到视频文件时报错是VFW_E_NOT_FOUND(值为0x80040216)
  71. //并不是所有的视频格式都支持将数据输出到内存,因此对于有些格式的视频将无法打开
  72. //会报错VFW_E_NOT_FOUND
  73. //-----------------------------------------------------------------------------
  74. VIPFunc(HRESULT)InitVIP
  75. (
  76.         VIPP,                                                //对象
  77.         WCHAR*szVideoFilePath,                //视频文件的路径
  78.         FnOnGetInfo,                                //取得信息的回调函数,可为NULL
  79.         FnOnRender,                                        //每渲染一帧的回调函数,可为NULL
  80.         BOOL bRenderAudio,                        //是否渲染声音
  81.         void*pUserData                                //用户自定义信息
  82. );

  83. //=============================================================================
  84. //CleanupVIP;
  85. //清理VIP。用完后必须调用一次。
  86. //-----------------------------------------------------------------------------
  87. VIPFunc(void)CleanupVIP(VIPP);

  88. //=============================================================================
  89. //播放控制类:
  90. //-----------------------------------------------------------------------------
  91. VIPFunc(HRESULT)VIPPlay(VIPP);//播放
  92. VIPFunc(HRESULT)VIPStop(VIPP);//停止
  93. VIPFunc(HRESULT)VIPSetRate(VIPP,double);//设置播放速度
  94. VIPFunc(HRESULT)VIPGetRate(VIPP,double*);//取得播放速度
  95. VIPFunc(HRESULT)VIPSetTime(VIPP,REFTIME);//设置播放位置
  96. VIPFunc(HRESULT)VIPGetTime(VIPP,REFTIME*);//取得播放位置
  97. VIPFunc(HRESULT)VIPCheckCompleted(VIPP,BOOL*pCompleted);//检查是否播放完

  98. #endif // !_VIDEO_INTERNAL_PLAYER_
复制代码
代码是用C++写的,但是是C的接口方式。其实C++也还是很不错的语言,但是需要用户合理使用它,别它有什么特性你就用什么特性,你只用最应该用的特性才是。

没有范例的工程下载:
http://pan.baidu.com/s/1mg826E0(访问密码:8xyn)

有范例的工程下载:(有个敖厂长的MC视频所以比较大。。但是它能直接用源码教你怎么用。)
http://pan.baidu.com/s/1qWLR9W4(访问密码:96q7)

好像bilibili的HLV格式的视频直接下载下来后不能用这个播放,必须用格式工厂转换成别的格式才行(搞成AVI、MP4、WMV或RMVB等)
这个程序并不带任何解码器,它只是一个使用了DirectShow的播放器,以及一个用来提取BMP的傀儡解码器。
建议大家先装好解码器,再使用这个东西播放,否则可能会遇到因为格式问题无法播放(缺少解码器)。
大家如果要用这个东西编写自己的播放器,我觉得你们可以考虑给自己的程序带上几个解码器,然后用regsvr32注册这些解码器,这样大概就能啥都播放了。
回复

使用道具 举报

1111

主题

1651

回帖

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
244
威望
743 点
宅币
24237 个
贡献
46222 次
宅之契约
0 份
在线时间
2297 小时
注册时间
2014-1-26
 楼主| 发表于 2014-10-3 16:09:16 | 显示全部楼层
20141003051051.png
回复 赞! 靠!

使用道具 举报

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-4-20 17:26 , Processed in 0.039753 second(s), 34 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表