文档章节

AVPlayer 之avcore模块

Jackarain
 Jackarain
发布于 2012/04/20 00:00
字数 1352
阅读 1319
收藏 1

avcore模块介绍

avcore事实上它只是一个对外的c++类接口, 目前基于windows实现. 在avcore中, avplayer是一个对外的接口, 因降低依赖关系, 采用pimpl方式实现, 其实现是由player_impl完成的. 也就是说, 在avcore中是由player_impl实现, 由avplayer导出c++接口.

avplayer类

avplayer是一个向外部导出接口的类, 其接口如下:

// 打开媒体类型.
#define MEDIA_TYPE_FILE 0
#define MEDIA_TYPE_BT   1
#define MEDIA_TYPE_HTTP 2
#define MEDIA_TYPE_RTSP 3

// 渲染模式.
#define RENDER_DDRAW	0
#define RENDER_D3D	1
#define RENDER_OGL	2

class EXPORT_API avplayer
{
public:
    avplayer(void);
    ~avplayer(void);

public:
    // 包含实现类
    HWND create_window(LPCTSTR player_name);

    // 销毁窗口, 只能撤销是由create_window创建的窗口.
    BOOL destory_window();

    // 子类化一个存在的窗口, in_process参数表示窗口是否在同一进程中.
    BOOL subclasswindow(HWND hwnd, BOOL in_process = TRUE);

public:
    // 打开一个媒体文件
    // movie 文件名.
    // media_type 表示打开的媒体类型.
    // render_type 表示播放渲染模式, 默认是ddraw渲染.
    // 注意, 这个函数只打开文件, 但并不播放, 重新打开文件前, 必
    // 须关闭之前的媒体文件, 否则可能产生内存泄漏! 另外, 在播放
    // 前, avplayer必须拥有一个窗口.
    BOOL open(const char *movie, int media_type, int render_type = RENDER_DDRAW);

    // 播放索引为index的文件, index表示在播放列表中的
    // 位置计数, 从0开始计算, index主要用于播放多文件的bt
    // 文件, 单个文件播放可以使用直接默认为0而不需要填写
    // 参数.
    BOOL play(int index = 0);

    // 暂停播放.
    BOOL pause();

    // 继续播放.
    BOOL resume();

    // 停止播放.
    BOOL stop();

    // 关闭媒体, 如果打开的是一个bt文件, 那么
    // 在这个bt文件中的所有视频文件将被关闭.
    BOOL close();

    // seek到某个时间播放, 单位是视频时长的百分比.
    void seek_to(double fact);

    // 设置声音音量大小.
    void volume(double vol);

    // 全屏切换.
    BOOL full_screen(BOOL fullscreen);

    // 返回当前播放时间.
    double curr_play_time();

    // 当前播放视频的时长, 单位秒.
    double duration();

    // 当前播放视频的高, 单位像素.
    int video_width();

    // 当前播放视频的宽, 单位像素.
    int video_height();

    // 返回当前播放列表中的媒体文件数.
    int media_count();

    // 返回播放列表index位置的媒体文件名.
    // 参数name应该在外部分配内存, 通过size参数传入分配的
    // 内存大小. 成功返回0, 返回-1表示失败, 返回大于0表示
    // name分配的内存不够, 返回值为index对应的文件名长度.
    int query_media_name(int index, char *name, int size);

    // 返回当前窗口句柄.
    HWND get_wnd();

private:
    player_impl *m_impl;
};

由上可以看出使用方法是:

  1. 通过create_window来创建一个窗口或通过subclasswindow附加到一个已有的窗口上.
  2. 通过open函数来打开要播放的视频, 并指定视频源的类型(由上面几个宏指定).
  3. 调用play函数开始播放(注意index是为BT中多视频播放而设置的, 单个文件播放默认为0即可).
  4. 可以调用pause或resume来暂时切换, 以及全屏切换.

注意, 内部实现了在播放窗口上点击鼠标左键按窗口宽进行seek, 鼠标右键暂停, F2全屏切换.

player_impl实现类

player_impl实现了avplayer所有接口, 实现代码在player_impl.cpp中, 下面简单介绍下一些主要的函数实现.

  1. open函数主要的功能主要完成判断播放的媒体类型, 根据文件类型创建相应的媒体源(media_source), 然后调用initialize初始化播放器. 并在初始化播放器之后, 初始化音频和视频的渲染器(分别是调用init_audio和init_video, 以及configure函数完成), 这个函数基本上完成了装配一个avplay播放器的过程, 其它的函数基本上辅助性的了.

  2. 在player_impl.cpp中你可能会看到一个win_data的结构, 也许你第一眼会很疑惑它是用来干嘛的, 现在说下: 这个结构是用于create_window函数创建窗口时, Hook窗口过程使之回调到成员函数win_wnd_proc中. 这个原理是以前从MFC那里学来的, 通过在创建窗口前创建一个HCBT_CREATEWND钩子, 之后的创建窗口调用CreateWindowEx时还在未回调窗口过程之前, 就进入HCBT_CREATEWND所设定的钩子, 从而提前获得HWND, 当窗口创建完成之后, 所有消息都可以通过win_wnd_proc来完成回调, 更具体的见代码或理解MFC框架原理(注意这里也可以使用WTL的Thunk技术来实现, 本人比较懒, 采用了更简单的方式).

  3. subclasswindow用于附加一个不同由player_impl创建的窗口, 这个其实就是类似MPlayer中的指定窗口渲染.

  4. win_wnd_proc窗口消息处理函数, WM_CREATE消息启动了一个ID_PLAYER_TIMER定时器, 用于100毫秒后检测视频的宽高, 然后按这个宽高设置窗口大小, 另外还有一些简单的消息处理, 最值的注意的是如果在ddraw的overlay模式渲染的话, 因为设置了colorkey是RGB(0, 0, 1),所以每次WM_PAINT消息过来时, 必须使用这个颜色的画刷之类去填充窗口背景.

以上基本上就是avcore的全部内容了, 还是相当简单的.

https://github.com/Jackarain/avplayer/wiki/avcore

© 著作权归作者所有

Jackarain

Jackarain

粉丝 225
博文 17
码字总数 10627
作品 4
杭州
私信 提问
加载中

评论(18)

霄霄月月
霄霄月月
好的 谢谢了啊 ,
Jackarain
Jackarain 博主

引用来自“bruce_hou”的评论

难道是我调用的问题,我刚刚通过邮件把我的简单的源文件发给你了,还有一个STOP函数的问题,你看一下 给我做一个示范嘛,谢谢了

stop确实在后面的版本中存在一个小问题, 不过刚刚修正了, 呵呵. seek_to的范例我已经在邮件中发你了
霄霄月月
霄霄月月
难道是我调用的问题,我刚刚通过邮件把我的简单的源文件发给你了,还有一个STOP函数的问题,你看一下 给我做一个示范嘛,谢谢了
Jackarain
Jackarain 博主

引用来自“bruce_hou”的评论

水哥 看看你测试一下seek_to 这个函数 好像有点问题,只要一seek就到末尾不管设置的秒数是多少

不会呀, 我测试过呀, 没问题
霄霄月月
霄霄月月
水哥 看看你测试一下seek_to 这个函数 好像有点问题,只要一seek就到末尾不管设置的秒数是多少
Jackarain
Jackarain 博主

引用来自“bruce_hou”的评论

水手,最新版的avcore.dll有问题 编译出来会出现vs2010 error LNK2019: 无法解析的外部符号这一类的错误,替换原来的就没有问题,请查看是什么问题造成的谢谢了哈

lib文件也要替换, link错误是lib文件引起的
霄霄月月
霄霄月月
水手,最新版的avcore.dll有问题 编译出来会出现vs2010 error LNK2019: 无法解析的外部符号这一类的错误,替换原来的就没有问题,请查看是什么问题造成的谢谢了哈
Jackarain
Jackarain 博主

引用来自“bruce_hou”的评论

引用来自“Jack.arain”的评论

引用来自“bruce_hou”的评论

double curr_play_time();这个函数调用不正确 不知道是不是bug

重新修改了curr_play_time的实现, 你更新下代码看看?

还是不正常, 我用一个定时器来刷新在对话框中显示的播放时间 但是一开始播放就不是从0开始的 win。curr——play——time()返回的不是0而是一些随机数

注意, 那个是浮点数, 单位是秒.
霄霄月月
霄霄月月

引用来自“Jack.arain”的评论

引用来自“bruce_hou”的评论

double curr_play_time();这个函数调用不正确 不知道是不是bug

重新修改了curr_play_time的实现, 你更新下代码看看?

还是不正常, 我用一个定时器来刷新在对话框中显示的播放时间 但是一开始播放就不是从0开始的 win。curr——play——time()返回的不是0而是一些随机数
Jackarain
Jackarain 博主

引用来自“bruce_hou”的评论

double curr_play_time();这个函数调用不正确 不知道是不是bug

重新修改了curr_play_time的实现, 你更新下代码看看?
基于ffmpeg并支持p2p(bt), http, rtsp的播放器 avplayer

一直以来, 在多媒体播放器这块, 即使目前有许多开源的播放器项目, 但要写一个播放器仍然是件非常困难的事, 如果在windows上你有可能需要熟悉DShow, 另外的话, 你需要学习一堆开源项目(比如F...

Jackarain
2012/04/06
5.4K
6
我想实现这么一个设想,我的avplayer是放在一个view上的,现在我想在这个view上添加一个tap点击事件,点击的时候会弹出两个view 但是avplayer的那个不会消失,为什么加不上去??这样不可以实现吗??

@珲少 你好,想跟你请教个问题:我想实现这么一个设想,我的avplayer是放在一个view上的,现在我想在这个view上添加一个tap点击事件,点击的时候会弹出两个view 但是avplayer的那个不会消失,...

素无恒
2015/12/20
148
2
AVFoundation开发秘籍笔记-04视频播放

一、播放功能综述 1、AVPlayer AVPlayer用来播放基于时间的视听媒体的控制器对象。支持播放从本地、分步下载或通过HTTP Live Streaming协议得到的流媒体,并在多种播放场景中播放这些视频资源...

竹与豆
2018/05/25
0
0
【开源访谈】AVPlayer 作者王功铭访谈实录

关于开源访谈 开源访谈是开源中国推出的一系列针对国内优秀开源软件作者的访谈,以文字的方式记录并传播。我们希望开源访谈能全面的展现国内开源软件、开源软件作者的现状,着实推动国内开源...

虫虫
2012/11/27
5.8K
31
AVFoundation 视频播放

1. 播放视频综述 AVFoundation 对于播放封装了主要的三个类 AVPlay、AVPlayerLayer 和 AVPlayerItem。 AVPlayer AVPlayer 是一个用于播放基于时间的试听媒体的控制器对象,可以播放本地、分布...

CISay
09/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Podman 使用指南

> 原文链接:Podman 使用指南 Podman 原来是 CRI-O 项目的一部分,后来被分离成一个单独的项目叫 libpod。Podman 的使用体验和 Docker 类似,不同的是 Podman 没有 daemon。以前使用 Docker...

米开朗基杨
45分钟前
5
0
拯救 项目经理个人时间的5个技巧

优秀的项目经理都有一个共同点,那就是良好的时间管理能力。专业的项目经理会确保他们的时间投入富有成效,尽可能避免时间浪费。 时间管理叫做GTD,即Getting Things Done——“把事情做完”...

Airship
今天
6
0
LNMP环境介绍,Mariadb安装,服务管理,mariadb安装3

LNMP环境介绍 Nginx 处理的请求有两种,分为 静态与动态 图片,js,css,视频,音频,flash 等都是静态请求,这些数据都不是保存在数据库里面的 动态请求一般来说,需要的数据是在数据库里面...

doomcat
今天
1
0
前端技术之:Prisma Demo服务部署过程记录

安装前提条件: 1、已经安装了docker运行环境 2、以下命令执行记录发生在MackBook环境 3、已经安装了PostgreSQL(我使用的是11版本) 4、Node开发运行环境可以正常工作 首先需要通过Node包管...

popgis
今天
7
0
数组和链表

数组 链表 技巧一:掌握链表,想轻松写出正确的链表代码,需要理解指针获引用的含义: 对指针的理解,记住下面的这句话就可以了: 将某个变量赋值给指针,实际上就是将这个变量的地址赋值给指...

code-ortaerc
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部