下面我们来讲解一下关于EasyPlayerPro接口的调用,主要分为C++和C#两种语言,C++也可以基于VC和QT进行开发,C++以VC MFC框架为例进行讲解,C#以Winform框架为例进行讲解。

  1. VC开发EasyPlayerPro
    首先建一个基于MFC Dialog的工程,取名叫EasyPlayerPro,关于界面逻辑的处理过程就不做过多赘述了,大家有兴趣的可以去看EasyPlayerPro项目代码;下面我们讲解一下EasyPlayerPro的调用流程:

    (1) 打开一个流或文件进行播放
    通过EasyPlayerPro_Open打开一个流或者本地文件,打开以后即播放,不需要调用EasyPlayerPro_Play方法,调用完成后,注意,比如拉网络流的时候,由于Open函数是非阻塞而立即返回的,所以,播放过程可能尚未初始化完成,从而获取流的信息可能获取不到,正确的做法是在线程或者计时器里面轮询获取;Open完成后,我们可以对一些参数进行设置,比如设置OSD和图片叠加,显示模式,音量大小等:

    // player open filem_player = EasyPlayerPro_Open(str, m_stcVideoWnd->GetSafeHwnd());if (m_player){m_bPlayPause = FALSE;SetTimer(TIMER_ID_PROGRESS, 1000, NULL);m_bOpening = TRUE;//字幕和图片叠加////  EasyPlayerPro_SetLogo  设置台标/LOGO//      player              - 指向 EasyPlayerPro_Open 返回的 player 对象//      bIsUse              - 是否使用水印 1=启用 0=不启用//      ePos                - 台标位置:1==leftttop 2==righttop 3==leftbottom 4==rightbottom//      eStyle              -  水印的风格,见WATERMARK_ENTRY_TYPE声明//      x                   - 水印左上角位置x坐标//      y                   - 水印左上角位置y坐标//      width               - 宽//      height              - 高//      logopath            - 水印图片路径EasyPlayerPro_SetLogo (m_player, 1, 2, 3, 0, 0, 0, 0, "C:\\Dingshuai\\Project\\Easylogo.png");//  EasyPlayerPro_SetOSD  设置叠加字幕//      player              - 指向 EasyPlayerPro_Open 返回的 player 对象//      bIsUse              - 是否使用水印 1=启用 0=不启用 -1=删除//      nMoveType           - 移动类型:0--固定位置,1--从左往右,2--从右往左,//      R,G,B               - 字体颜色对应三个分量红绿蓝0-255//      x                   - 字幕显示左上角位置x坐标//      y                   - 字幕显示左上角位置y坐标//      weight              - 字体权重,见如下声明// /* Font Weights */// #define FW_DONTCARE         0// #define FW_THIN             100// #define FW_EXTRALIGHT       200// #define FW_LIGHT            300// #define FW_NORMAL           400// #define FW_MEDIUM           500// #define FW_SEMIBOLD         600// #define FW_BOLD             700// #define FW_EXTRABOLD        800// #define FW_HEAVY            900// #define FW_ULTRALIGHT       FW_EXTRALIGHT// #define FW_REGULAR          FW_NORMAL// #define FW_DEMIBOLD         FW_SEMIBOLD// #define FW_ULTRABOLD        FW_EXTRABOLD// #define FW_BLACK            FW_HEA//      width               - 宽//      height              - 高//      fontname            - 字体名称,如“宋体”“楷体”“隶书”“华文行楷”......//      tittleContent       - OSD显示内容EasyPlayerPro_SetOSD (m_player, 1, 1, 0, 255, 0,700, 100, 200, 0, -29, "隶书", "你说你爱了不该爱的人,你的心中满是伤痕!");}

(2) 暂停和单步播放

void CplayerDlg::OnBnClickedBtnPause()
{// TODO: 在此添加控件通知处理程序代码if (!m_bPlayPause) EasyPlayerPro_Pause(m_player);else EasyPlayerPro_Play(m_player);m_bPlayPause = !m_bPlayPause;CSkinButton* pBtn = (CSkinButton*)GetItemByName(_T("Pause"));if(pBtn){if (m_bPlayPause){pBtn->SetBtnText(_T("播放"));}   else{pBtn->SetBtnText(_T("暂停"));}}
}void CplayerDlg::OnBnClickedBtnPlayByFrame()
{// TODO: 在此添加控件通知处理程序代码// EasyPlayerPro_StepPlay(m_player);m_bPlayPause = TRUE;CSkinButton* pBtn = (CSkinButton*)GetItemByName(_T("Pause"));if(pBtn){if (m_bPlayPause){pBtn->SetBtnText(_T("播放"));}   else{pBtn->SetBtnText(_T("暂停"));}}
}

这里直接调用即可,不做过多赘述。

(3) 快放和慢放

void CplayerDlg::OnBnClickedBtnRatePlay()
{int nRate = 0;switch(m_speedRate){case    SPEED_SLOW_X4:nRate = 25;break;case    SPEED_SLOW_X2:nRate = 50;break;case    SPEED_NORMAL:   nRate = 100;break;case    SPEED_FAST_X2:nRate = 200;break;case    SPEED_FAST_X4:nRate = 300;break;case    SPEED_FAST_X8:nRate = 400;break;case    SPEED_FAST_X16:nRate = 500;break;case    SPEED_FAST_X64:nRate = 600;break;}EasyPlayerPro_Setparam(m_player, EASY_PARAM_PLAY_SPEED, &nRate);
}

目前定义慢放范围为2倍和4倍,快放范围为2,4,8,16,64倍,超过这个范围则无明显反应或者意义。

(4) 抓图接口调用

void CplayerDlg::OnBnClickedBtnSnapshot()
{// TODO: 在此添加控件通知处理程序代码// TCHAR sPath[512];memset(sPath, 0x00, sizeof(TCHAR) * 512);GetWorkDirectory(sPath, 512);int nPathLen = _tcslen(sPath);if ((sPath[nPathLen - 1] != '/' && sPath[nPathLen - 1] != '\\')){sPath[nPathLen] = '\\';}unsigned int timestamp = (unsigned int)time(NULL);time_t tt = timestamp;struct tm _time;::localtime_s(&_time, &tt);char szTime[64] = { 0, };strftime(szTime, 32, "\\pic_%Y%m%d%H%M%S.jpg", &_time);CString strTime = (CString)szTime;CString sScreenPath = _T("");sScreenPath.Format(_T("%s%s"), sPath, _T("ScreenShot"));bool bSec = EnsureDirExist(sScreenPath);sScreenPath += strTime;USES_CONVERSION;EasyPlayerPro_Snapshot(m_player, T2A(sScreenPath), 0, 0, 1000);}

抓图接口直接调用即可,注意保存的路径需要存在,否则,抓图保存将会失败。

(5) 录像接口调用

void CplayerDlg::OnBnClickedBtnRecord()
{// TODO: 在此添加控件通知处理程序代码if(!m_player)return ;CSkinButton* pBtn = (CSkinButton*)GetItemByName(_T("Record"));if (!pBtn){return;}if (!m_bRecording){pBtn->SetBtnText(_T("停止录像"));TCHAR sPath[512];memset(sPath, 0x00, sizeof(TCHAR)*512);GetWorkDirectory(sPath, 512);int nRecordPathLen = _tcslen(sPath);if ((sPath[nRecordPathLen - 1] != '/' && sPath[nRecordPathLen - 1] != '\\')){sPath[nRecordPathLen] = '\\';}unsigned int timestamp = (unsigned int)time(NULL);time_t tt = timestamp;struct tm _time;::localtime_s(&_time, &tt);char szTime[64] = { 0, };strftime(szTime, 32, "\\record_%Y%m%d%H%M%S.mp4", &_time);CString strTime = (CString)szTime;CString sRecordPath = _T("");sRecordPath.Format(_T("%s%s"), sPath, _T("Record"));bool bSec = EnsureDirExist(sRecordPath);sRecordPath += strTime;UpdateData(TRUE);CString sRecDuration = _T("");if(m_editRecPieceTime)m_editRecPieceTime->GetWindowText(sRecDuration);int nDuration =  _ttoi( sRecDuration.GetBuffer());//m_SNPlayOcx.EasyPlayPro_PlayOcx_Record(sRecordPath, m_sRtspUrl, nDuration);//m_SNPlayOcx.EasyPlayPro_PlayOcx_Record(_T("D:\\test.mp4"), m_sRtspUrl);USES_CONVERSION;EasyPlayerPro_Record(m_player, T2A(sRecordPath), nDuration);m_lRecordTime = 0;//IDC_STATIC_RECORD_STATUSSetTimer(TIMER_RECORD_STATUS, 300, NULL);} else{pBtn->SetBtnText(_T("录像"));EasyPlayerPro_Stoprecord(m_player);KillTimer(TIMER_RECORD_STATUS);EasyPlayerPro_Getparam(m_player, EASY_PARAM_RECORD_TIME, &m_lRecordTime);EasyPlayerPro_Getparam(m_player, EASY_PARAM_RECORD_PIECE_ID, &m_lRecordSliceUp);int thh, tmm, tss = 0;thh = m_lRecordTime / 3600;tmm = (m_lRecordTime % 3600) / 60;tss = (m_lRecordTime % 60);CString sShowRec = _T("");if (m_lRecordSliceUp > -1)sShowRec.Format(_T("录像已停止 录制时间:%02d:%02d:%02d  切片ID:%d"), thh, tmm, tss, m_lRecordSliceUp);elsesShowRec.Format(_T("录像已停止 录制时间:%02d:%02d:%02d"), thh, tmm, tss);SetString(4, sShowRec);m_lRecordTime = 0;//IDC_STATIC_RECORD_STATUS}m_bRecording = !m_bRecording;
}

EasyPlayPro_PlayOcx_Record接口调用进行录像,EasyPlayerPro_Stoprecord接口调用停止录像,EasyPlayerPro_Getparam接口获取录像的时间和当前录像的PieceId, 具体参数见上一篇文章EasyPlayerPro接口说明。

(6) 本地文件和点播拖拽

 a. 进度显示计时
    case TIMER_ID_PROGRESS://进度条计时器{
#if 1if (m_totalDuration <= 0){LONGLONG ltotal = 0;EasyPlayerPro_Getparam(m_player, EASY_PARAM_MEDIA_DURATION, &ltotal);if (ltotal>1){m_totalDuration = ltotal/1000;int totalSeconds = (int)m_totalDuration;int gTotalSeconds = totalSeconds;int gTotalMinute = (int)(totalSeconds / 60);int nTotalHour = (int)(gTotalMinute / 60);  //时int nTotalMinute = (int)(gTotalMinute % 60);//分int totalSecond = (int)(totalSeconds % 60); //秒m_strPlayFileTime.Format(_T("%02d:%02d:%02d"), nTotalHour, nTotalMinute, totalSecond);if (m_sliderPlay){m_sliderPlay->SetRange(0, m_totalDuration);m_sliderPlay->SetPos(0);                    }                       m_sliderPlay->EnableWindow(TRUE);}}LONGLONG llCurPos   = 0;    LONGLONG llPos  = 0;    EasyPlayerPro_Getparam(m_player, EASY_PARAM_MEDIA_POSITION, &llPos);llCurPos = llPos/1000;TRACE("Position == %d\r\n",llCurPos);int totalSeconds = (int)llCurPos;int gTotalSeconds = totalSeconds;int gTotalMinute = (int)(totalSeconds / 60);int nTotalHour = (int)(gTotalMinute / 60);  //时int nTotalMinute = (int)(gTotalMinute % 60);//分int totalSecond = (int)(totalSeconds % 60); //秒CString strTemp = _T("");if (m_totalDuration>0  ){if (llCurPos<m_totalDuration){strTemp.Format(_T("%02d:%02d:%02d/%s"), nTotalHour, nTotalMinute, totalSecond, m_strPlayFileTime);if (m_sliderPlay){m_sliderPlay->SetPos(llCurPos);}} else{
#if 0KillTimer(TIMER_ID_PROGRESS);PlayerCloseFile();SetString(2,_T(""));m_totalDuration = -1;m_sliderPlay->SetRange(0, 2000);m_sliderPlay->SetPos(0);    m_speedRate = 0;
#endifOnBnClickedBtnClose();strTemp = _T("");}}elsestrTemp.Format(_T("%02d:%02d:%02d/../../.."), nTotalHour, nTotalMinute, totalSecond);SetString(2,strTemp);
#endif}break;

b. 拖拽进度条OnHScroll消息处理

    if (m_sliderPlay==pSliderTmp){if (nSBCode == 5){int nPos = m_sliderPlay->GetPos();TRACE("nPos==%d\r\n", nPos);//如果处于断点循环
#if 0   if (m_bLoopAB){if(nPos<m_dbBreakPtA || nPos>m_dbBreakPtB){   nPos = m_dbBreakPtA;}}
#endifif (m_totalDuration>0){                       EasyPlayerPro_Seek(m_player, nPos*1000);}}}

c. 音量调节进度条OnHScroll消息处理

    else if (m_sliderSound == pSliderTmp)//音量调节{int nValue = m_sliderSound->GetPos();nValue -= 255;EasyPlayerPro_Setparam(m_player, EASY_PARAM_AUDIO_VOLUME, &nValue);}
  1. C#开发EasyPlayerPro

C#我真不擅长,故此,只对libEasyPlayerPro的调用做简单介绍;
首先,创建一个Winform程序(类似于MFC的Dialog程序),然后导入 libeasyplayerpro.dll,生成实体类,即可调用接口。
(1) libeasyplayerpro.dll接口类化
导入dll,生产类,声明需要用到的参数列表如下:

        public enum tagEASY_PARAM_ID{//++ public// duration & positionPARAM_MEDIA_DURATION = 0x1000,PARAM_MEDIA_POSITION,// media detail infoPARAM_VIDEO_WIDTH,PARAM_VIDEO_HEIGHT,// video display modePARAM_VIDEO_MODE,// audio volume controlPARAM_AUDIO_VOLUME,// playback speed controlPARAM_PLAY_SPEED,// video decode thread countPARAM_DECODE_THREAD_COUNT,// visual effect modePARAM_VISUAL_EFFECT,// audio/video sync diffPARAM_AVSYNC_TIME_DIFF,// player event callbackPARAM_PLAYER_CALLBACK,// audio/video streamPARAM_AUDIO_STREAM_TOTAL,PARAM_VIDEO_STREAM_TOTAL,PARAM_SUBTITLE_STREAM_TOTAL,PARAM_AUDIO_STREAM_CUR,PARAM_VIDEO_STREAM_CUR,PARAM_SUBTITLE_STREAM_CUR,//-- public//++ for adevPARAM_ADEV_RENDER_TYPE = 0x2000,//-- for adev//++ for vdevPARAM_VDEV_RENDER_TYPE = 0x3000,PARAM_VDEV_FRAME_RATE,//-- for vdev//++ for renderPARAM_RENDER_UPDATE = 0x4000,PARAM_RENDER_START_PTS,//-- for render};

声明Easyplayerpro接口如下:

        //初始化播放视频[DllImport("libEasyplayerpro.dll", EntryPoint = "EasyPlayerPro_Open", CallingConvention = CallingConvention.Cdecl)]static extern IntPtr EasyPlayerPro_Open(string file, IntPtr hwnd);//关闭视频[DllImport("libEasyplayerpro.dll", EntryPoint = "EasyPlayerPro_Close", CallingConvention = CallingConvention.Cdecl)]static extern void EasyPlayerPro_Close(IntPtr player);//播放视频[DllImport("libEasyplayerpro.dll", EntryPoint = "EasyPlayerPro_Play", CallingConvention = CallingConvention.Cdecl)]static extern void EasyPlayerPro_Play(IntPtr player);//单针播放视频[DllImport("libEasyplayerpro.dll", EntryPoint = "EasyPlayerPro_StepPlay", CallingConvention = CallingConvention.Cdecl)]static extern void EasyPlayerPro_StepPlay(IntPtr player);//暂停视频[DllImport("libEasyplayerpro.dll", EntryPoint = "EasyPlayerPro_Pause", CallingConvention = CallingConvention.Cdecl)]static extern void EasyPlayerPro_Pause(IntPtr player);//设置时长[DllImport("libEasyplayerpro.dll", EntryPoint = "EasyPlayerPro_Seek", CallingConvention = CallingConvention.Cdecl)]static extern void EasyPlayerPro_Seek(IntPtr player, long ms);//设置窗口[DllImport("libEasyplayerpro.dll", EntryPoint = "EasyPlayerPro_Resize", CallingConvention = CallingConvention.Cdecl)]static extern void EasyPlayerPro_Resize(IntPtr player, int type, int x, int y, int w, int h);//截图[DllImport("libEasyplayerpro.dll", EntryPoint = "EasyPlayerPro_Snapshot", CallingConvention = CallingConvention.Cdecl)]static extern int EasyPlayerPro_Snapshot(IntPtr player, string file, int w, int h, int wait);//设置参数[DllImport("libEasyplayerpro.dll", EntryPoint = "EasyPlayerPro_Setparam", CallingConvention = CallingConvention.Cdecl)]static extern void EasyPlayerPro_Setparam(IntPtr player, uint id, ref IntPtr param);//得到参数[DllImport("libEasyplayerpro.dll", EntryPoint = "EasyPlayerPro_Getparam", CallingConvention = CallingConvention.Cdecl)]static extern void EasyPlayerPro_Getparam(IntPtr player, uint id, ref IntPtr param);

声明一个指针变量用于存放播放器指针:
private IntPtr mPlayer;
创建一个按钮,点击消息处理:

    private void button1_Click(object sender, EventArgs e){                                                     EasyPlayerPro_Open("rtmp://live.hkstv.hk.lxdns.com/live/hks", panel1.Handle);}

其中,panel1是创建的一个pannel,用于显示视频的窗口;
这样,其他接口调用也类似,具体可参考C++的调用流程,这里不做过多赘述;

关于EasyPlayerPro

EasyPlayerPro是一款全功能的流媒体播放器,支持RTSP、RTMP、HTTP、HLS、UDP、RTP等多种流媒体协议播放、支持本地文件播放,支持本地抓拍、本地录像、播放旋转、多屏播放等多种功能特性,稳定、高效、可靠,支持Windows、Android、iOS三个平台,目前在多家教育、安防、行业型公司,都得到的应用,广受好评!

EasyPlayerPro:https://github.com/EasyDSS/EasyPlayerPro

点击链接加入群【EasyPlayer & EasyPlayerPro】:544917793

获取更多信息

邮件:support@easydarwin.org

WEB:www.EasyDarwin.org

Copyright © EasyDarwin.org 2012-2017

EasyPlayerPro(Windows)流媒体播放器开发之跨语言调用相关推荐

  1. EasyPlayerPro(Windows)流媒体播放器开发之框架讲解

    EasyPlayerPro for Windows是基于ffmpeg进行开发的全功能播放器,开发过程中参考了很多开源的播放器,诸如vlc和ffplay等,其中最强大的莫过于vlc,但是鉴于vlc框架过 ...

  2. EasyPlayerPro(Windows)流媒体播放器开发之接口设计

    EasyPlayerPro(windows)接口说明如下: EasyPlayerPro_Open 说明:打开一个媒体流或者媒体文件进行播放,同时返回一个 player 对象指针 参数说明: fileU ...

  3. EasyPlayerPro(Windows)流媒体播放器开发之ffmpeg log输出报错

    EasyPlayerPro主要基于ffmpeg进行开发,在EasyPlayerPro开发过程中,曾遇到一个相对比较棘手的问题,该问题一般在播放不是很标准的流或者网络情况较差,容易出现丢帧的情况特别容易 ...

  4. Java如何跨语言调用Python/R训练的模型

    在 如何使用sklearn进行在线实时预测(构建真实世界中可用的模型) 这篇文章中,我们使用 sklearn + flask 构建了一个实时预测的模型应用.无论是 sklearn 还是 flask,都 ...

  5. 跨语言调用Hangfire定时作业服务

    背景 Hangfire允许您以非常简单但可靠的方式执行后台定时任务的工作.内置对任务的可视化操作.非常方便. 但令人遗憾的是普遍都是业务代码和hagnfire服务本身聚合在一个程序中运行,极大的限制了 ...

  6. 使用thrift进行跨语言调用(php c# java)

    1:前言 实际上本文说的是跨进程的异构语言调用,举个简单的例子就是利用PHP写的代码去调C#或是java写的服务端.其实除了本文提供的办法还有其他办法,例如http+xml(json)等等都能做到. ...

  7. easyplayerpro 使用说明_EasyPlayerPro(Windows)流媒体播放器开发之ffmpeg log输出报错

    EasyPlayerPro主要基于ffmpeg进行开发,在EasyPlayerPro开发过程中,曾遇到一个相对比较棘手的问题,该问题一般在播放不是很标准的流或者网络情况较差,容易出现丢帧的情况特别容易 ...

  8. 多语言混合开发之易语言调用python算法

    点击上方↑↑↑蓝字[协议分析与还原]关注我们 " 扬长避短,发挥各自优势,建立多语言和谐共存的大好局面,介绍多语言的混合开发." 好久没有更新,深感抱歉,还有几天就要过年了,先在这 ...

  9. EasyPlayerPro安卓流媒体播放器实现Android H.265硬解码流程

    本文转自EasyDarwin团队成员John的博客:http://blog.csdn.net/jyt0551/article/details/74502627 H.265编码算法作为新一代视频编码标准 ...

最新文章

  1. $.when().done().then()的用法
  2. 经典日剧、电影、动漫
  3. oracleasm 建立时出错
  4. How is ngModelController initialized
  5. api报错 javaee maven_maven test 换javaee6 无法加载spring的配置文件 ?报错-问答-阿里云开发者社区-阿里云...
  6. 远程客户端连接MysqL数据库太慢解决方案
  7. redhat bash: yum: 未找到命令..._常用linux yum 命令和 vim命令,这几个要熟记
  8. 信息学奥赛一本通 2040:【例5.7】筛选法找质数 (普通筛 线性筛)
  9. Redis笔记(七)Java实现Redis消息队列
  10. 2-17 numpy模块使用
  11. 【LaTeX】 案例分析 (8) - 高等数学分析 Mathematica 实验报告
  12. 数据结构线性表-----静态链表
  13. oracle 同义词循环连,Oracle出现ORA-01775:同义词的循环链问题
  14. 蓝牙、Wifi与ZigBee无线传输技术中,谁比较占有优势
  15. 3.0_Linux如何连接网络
  16. Sexagenary Cycle(干支纪年)
  17. 最小的操作系统MenuetOS
  18. 3d打印利器FreeCAD入门教程之二----乐高积木块建模操作篇
  19. 质因子分解 Python
  20. 看完就会flink基础API

热门文章

  1. cifs文件服务器,samba - 为 UNIX 实现的 Windows SMB/CIFS 文件服务器
  2. 英汉互译简单的方法是什么?
  3. void和int函数的区别
  4. Flask学习笔记(四):基于Flask网页显示图片
  5. java判断oom_OOM排查
  6. python中对于bool布尔值的取反
  7. 网络安全中护网是什么意思?有CISP和NISP证书可以参加吗?
  8. 性能指标:QPS、TPS、系统吞吐量理解
  9. 计算机毕业论文net毕业设计家电维修保养信息系统net专业计算机毕业论文选题
  10. 【pac文件】win10自动配置代理