本文原文地址:http://www.cnblogs.com/over140/archive/2009/03/30/1421531.html

阿里云栖社区也有相关的视频开发案例:https://yq.aliyun.com/articles/51182

注意

本系列文章限于学习交流,注重过程,由于涉及公司,所以不提供源代码下载,非常抱歉!!但是请大家放心,核心、实现以及其他能够贴出来的代码我都会贴出来,并且争取尽所能的回答留言里的每一个问题,感谢大家关注,欢迎交流 :)

系列

1.     C# 视频监控系列(1):准备

2.     C# 视频监控系列(2):客户端——封装API

3.     C# 视频监控系列(3):客户端——连接服务器

4.     C# 视频监控系列(4):客户端——音频接收和抓图

5.     C# 视频监控系列(5):客户端——给服务器端发送字符串和录像(数据捕获)

6.     C# 视频监控系列(6):服务器端——封装API(上) [HikServer.dll]

7.     C# 视频监控系列(7):服务器端——封装API(下) [DS40xxSDK.dll]

8.     C# 视频监控系列(8):服务器端——预览和可被客户端连接

9.     C# 视频监控系列(9):服务器端——数据捕获(抓图 + 录像)

10.     C# 视频监控系列(10):服务器端——验证、设置画面质量、字幕叠加、板卡序列号

11.     C# 视频监控系列(11):H264播放器——封装API[HikPlayM4.dll]

12.     C# 视频监控系列(12):H264播放器——播放录像文件

13.     C# 视频监控系列(13):H264播放器——控制播放和截图

正文

一、控制播放

1.1     暂停/播放/停止

VC++ Code:


////////////////////////////////////////////////////////////////////////////////

//Funtion:Play or change the play speed to normal;

///////////////////////////////////////////////////////////////////////////////

void CPlayerDlg::OnPlay() 

{

    // TODO: Add your control notification handler code here

    Play();

}

void CPlayerDlg::Play()

{

    m_nSpeed=0;

    OnThrow0();

//#ifdef _TEST_CALLBACK

    if(m_bConvert)       

       Hik_PlayM4_SetDecCallBack(PORT,DecCBFun);

    else

        m_pMainMenu->EnableMenuItem(ID_FILE_CLOSE, FALSE);

//#endif

    if(m_bPlaying)

    {

        Hik_PlayM4_Play(PORT,GetDlgItem(IDC_SHOW)->m_hWnd);

    }

    else

    {

        if(m_bStreamType)

        {

            ::SetFilePointer(m_hStreamFile,m_nHeadSize,0,FILE_BEGIN);

            Hik_PlayM4_ResetSourceBuffer(PORT);

            SetEvent(m_hEventInput);

        }

        m_bPlaying = Hik_PlayM4_Play(PORT,GetDlgItem(IDC_SHOW)->m_hWnd);

        m_bSound=Hik_PlayM4_PlaySound(PORT);

        if(m_bPlaying)

            SetTimer(PLAY_TIMER,500,NULL);

        

    }

    if(m_bPlaying)

        SetPlayState();

    else

    {

        CString csError;

        csError.Format("Play the file faild.(%d)",Hik_PlayM4_GetLastError(PORT));

        AfxMessageBox(csError);

    }

    

}

//////////////////////////////////////////////////////////////////////////////

//Funtion:pause.

//////////////////////////////////////////////////////////////////////////////

void CPlayerDlg::OnPause() 

{

    // TODO: Add your control notification handler code here

    if(m_bPlaying)

    {

        m_bPause=!m_bPause;

        Pause(m_bPause);

    }

}

void CPlayerDlg::Pause(BOOL bPause)

{

    if(m_bPaused == bPause)

        return;

    m_bPaused=bPause;

    Hik_PlayM4_Pause(PORT,bPause);

    TRACE("PAUSE %d\n",m_bPaused);

}

/////////////////////////////////////////////////////////////////////////////

//Function: Stop

/////////////////////////////////////////////////////////////////////////////

void CPlayerDlg::OnStop() 

{

    // TODO: Add your control notification handler code here

    

    if(m_bPlaying)

    {

        Stop();

    }

    if(m_bConvert)

    {

       if(outFile!=NULL)

          closeWriffFiles();    

       if(yuvBuf!=NULL)

       {

           free(yuvBuf);

           yuvBuf=NULL;

       }

       m_bConvert=0;    

       //

    }

}

void CPlayerDlg::Stop()

{

    CButton *pButton;

    if(!m_bPlaying)

        return;

    KillTimer(PLAY_TIMER);

    if(Hik_PlayM4_StopSound())

    {

        m_bSound=FALSE;

        pButton = (CButton *)GetDlgItem(IDC_SOUND);

        pButton->SetIcon(m_hSoundStopIcon);

    }

    //continue before stop.Add by lgl at 9-19;

    m_bPause=FALSE;

    

    //stop

    m_bPlaying = !Hik_PlayM4_Stop(PORT);

    if(!m_bPlaying)    

    {

        SetStopState();

        if(m_bStreamType)

            ResetEvent(m_hEventInput);

    }

    

}

C#     Code:


        //是否暂停

        private bool isPause;

        /// <summary>

        /// 播放

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void btnPlay_Click(object sender, EventArgs e)

        {

            if (!string.IsNullOrEmpty(m_strPlayFileName))

            {

                //是否暂停->播放

                if (isPause)

                {

                    HikPlayer.Hik_PlayM4_Pause(PORT, false);

                    isPause = false;

                }

                else

                    OpenFile();

            }

        }

        /// <summary>

        /// 暂停

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void btnPause_Click(object sender, EventArgs e)

        {

            HikPlayer.Hik_PlayM4_Pause(PORT, true);

            isPause = true;

        }

        /// <summary>

        /// 停止

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void btnStop_Click(object sender, EventArgs e)

        {

            HikPlayer.Hik_PlayM4_Stop(PORT);

            HikPlayer.Hik_PlayM4_CloseFile(PORT);

            HikPlayer.Hik_PlayM4_RealeseDDraw();

            pVideo.Invalidate(true);

        }

代码说明:

1.     关于变量PORT、m_strPlayFileName和方法OpenFile可以看上篇文章的代码。

2.     注意Hik_PlayM4_Pause的第二个参数用法。

1.2     快进/慢进

VC++ Code:


//////////////////////////////////////////////////////////////////////////////

//Funtion: Fast

//////////////////////////////////////////////////////////////////////////////

void CPlayerDlg::OnFastForward() 

{

    // TODO: Add your control notification handler code here

    //Throw B-Frame ,improve the performance;

    

    if(Hik_PlayM4_Fast(PORT))

    {

        m_nSpeed++;

        if(m_nSpeed>0)

            OnThrow2();

        SetFastForwardState();        

    }    

}

//////////////////////////////////////////////////////////////////////////////

//Funtion: Slow;

//////////////////////////////////////////////////////////////////////////////

void CPlayerDlg::OnFastBackward() 

{

    // TODO: Add your control notification handler code here

    if(Hik_PlayM4_Slow(PORT))

    {

        m_nSpeed--;

        if(m_nSpeed<=0)

            OnThrow0();

        SetFastBackWardState();

    }

}

C#     Code:


        int m_nSpeed;

        /// <summary>

        /// 快进

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void btnFastForward_Click(object sender, EventArgs e)

        {

            if (HikPlayer.Hik_PlayM4_Fast(PORT))

            {

                m_nSpeed++;

                if (m_nSpeed > 0)

                    OnThrow2();

            }

        }

        /// <summary>

        /// 慢放

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void btnFastBackward_Click(object sender, EventArgs e)

        {

            //慢速播放

            if (HikPlayer.Hik_PlayM4_Slow(PORT))

            {

                //timer1.Interval

                m_nSpeed--;

                if (m_nSpeed <= 0)

                    OnThrow0();

            }

        }

        public void OnThrow0()

        {

            HikPlayer.Hik_PlayM4_ThrowBFrameNum(PORT, 0);

        }

        public void OnThrow2()

        {

            HikPlayer.Hik_PlayM4_ThrowBFrameNum(PORT, 2);

        }

代码说明:

1.     注意关于这两个函数API的说明:

Hik_PlayM4_Fast:快速播放,每次调用将使当前播放速度加快一倍,最多调用4次;要恢复正常播放调用Hik_PlayM4_Play(),从当前位置开始正常播放。

Hik_PlayM4_Slow:慢速播放,每次调用将使当前播放速度慢一倍;最多调用4次;要恢复正常播放调用Hik_PlayM4_Play。

1.3     开始/末尾

VC++ Code:


///////////////////////////////////////////////////////////////////////////////

//Funtion:Locate to the file head.

//////////////////////////////////////////////////////////////////////////////

void CPlayerDlg::OnGotoStart() 

{

    // TODO: Add your control notification handler code here

    if(m_bFileRefCreated)

        Hik_PlayM4_SetCurrentFrameNum(PORT,0);

    else

        Hik_PlayM4_SetPlayPos(PORT,0);

}

///////////////////////////////////////////////////////////////////////////////

//Funtion:Locate to the end.

//////////////////////////////////////////////////////////////////////////////

void CPlayerDlg::OnGotoEnd() 

{

    // TODO: Add your control notification handler code here

    if(m_bFileRefCreated)

    {

        //Note: May create many WM_FILE_END message. The best way is to synchronize the option;

        

        int nEndFrame=m_nTotalFrames;

        while(!Hik_PlayM4_SetCurrentFrameNum(PORT,nEndFrame--))

        {

            //TRACE("FrameNum is :%d\n",nEndFrame);

            if(nEndFrame==0)

                break;

        }

    }

    else

        Hik_PlayM4_SetPlayPos(PORT,1);

}

C#     Code:


        /// <summary>

        /// 开始位置

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void btnGotoStart_Click(object sender, EventArgs e)

        {

            HikPlayer.Hik_PlayM4_SetPlayPos(PORT, 0);

        }

        /// <summary>

        /// 末尾位置

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void btnGotoEnd_Click(object sender, EventArgs e)

        {

            HikPlayer.Hik_PlayM4_SetPlayPos(PORT, 1);

        }

代码说明:

1.     注意Hik_PlayM4_SetPlayPos的第二个参数取值范围是0-1之间,即可以理解0是开始位置,1是结束位置;但是有一点比较奇怪,每次都会延迟3秒,即到末尾后还播放3秒钟!

二、截图

VC++ Code:

//////////////////////////////////////////////////////////////////
//Function:The call back funtion for capture image!
/////////////////////////////////////////////////////////////////
void CALLBACK DisplayCBFun(long nPort,\
                           char * pBuf,long nSize,\
                           long nWidth,long nHeight,\
                           long nStamp,long nType,long nReceaved)
{
    if(!g_bCapPic)
        return;
    CString csFile;
    csFile.Format("capture%02d.bmp",pic);
    /*    switch(nType)
    {
    case T_UYVY:
    csFile="uyvy.bmp";
    break;
    case T_YV12:
    csFile="yv12.bmp";
    break;
    case T_RGB32:
    csFile="rgb.bmp";
    break;
    default: 
    return ;
}*/
    //Note:this funtion is slow,so if you want to save as a .bmp file,don't call! 
    if(!Hik_PLayM4_ConvertToBmpFile(pBuf,nSize,nWidth,nHeight,nType,csFile.GetBuffer(csFile.GetLength())))
    {
        CString csErr;
        csErr.Format("Convert to bmp faild(%d).",Hik_PlayM4_GetLastError(nPort));
        AfxMessageBox(csErr);
    }
    pic++;
    g_bCapPic=FALSE;
    
}

C#     Code:


        DisplayCBFun DisCB;

        /// <summary>

        /// 截图

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void btnCapImage_Click(object sender, EventArgs e)

        {

            DisCB = new DisplayCBFun(DisplayCBFun);

            HikPlayer.Hik_PlayM4_SetDisplayCallBack(PORT, DisCB);

        }

        /// <summary>

        /// 截图回调函数

        /// </summary>

        /// <param name="nPort"></param>

        /// <param name="pBuf"></param>

        /// <param name="nSize"></param>

        /// <param name="nWidth"></param>

        /// <param name="nHeight"></param>

        /// <param name="nStamp"></param>

        /// <param name="nType"></param>

        /// <param name="nReceaved"></param>

        public void DisplayCBFun(int nPort, IntPtr pBuf, int nSize, int nWidth, int nHeight, int nStamp, int nType, int nReceaved)

        {

            if (HikPlayer.Hik_PLayM4_ConvertToBmpFile(pBuf, nSize, nWidth, nHeight, nType, string.Format("C:\\capture{0}.bmp", nPort)))

            {

                MessageBox.Show("转换bmp失败!");

            }

            //停止回调

            HikPlayer.Hik_PlayM4_SetDisplayCallBack(PORT, null);

        }

代码说明:

1.     这里和源代码有点出入,他用的是g_bCapPic变量来控制是否捕获图片,我用的是设置委托实例和null来达到。API说明:设置抓图回调函数;注意要尽快返回,如果要停止回调,可以把回调函数指针DisplayCBFun设为NULL。

结束

现在在做语音部分,受阻中...

【转】C# 视频监控系列(13):H264播放器——控制播放和截图的更多相关文章

  1. C# 视频监控系列:学习地址汇总

    原文地址:http://www.cnblogs.com/over140/archive/2009/04/07/1429308.html 前言 对于视频监控系统大家应该是不陌生的,实施的路况信息.地铁. ...

  2. 【转】C# 视频监控系列(12):H264播放器——播放录像文件

    原文地址:http://www.cnblogs.com/over140/archive/2009/03/23/1419643.html?spm=5176.100239.blogcont51182.16 ...

  3. 百度播放器SDK 播放MP4格式视频有声音无画面问题解决

    此处为记录解决过程. 所链接使用的MP4格式视频为codec id是mp4v-20.使用手机自带播放器可以播放,使用百度云媒体播放器不能无画面.经调试,Android Baidu-Cloud-Play ...

  4. java调用本地播放器播放视频文件。调用本地播放器不能播放指定文件的说明。

    public class OpenExe extends HttpServlet { //打开本地播放器并播放视频 public static void openExe(String file) { ...

  5. phongap开发中安卓平台上如何调用第三方播放器来播放HLS视频

    前文曾经讲了关于在安卓平台上利用phonegap开发播放HLS的解决方案,其实最好的方案就是自己针对HLS视频开发自己的播放器,但是开发播放器是一个浩大的工程,必须对原生安卓开发非常熟悉,并且对视频播 ...

  6. iOS 多个播放器同时播放,双击全屏,单击退出全屏

    前言:公司需求如下:点击一个按钮播放一个视频,最多同时播放4个:双击某视频让其全屏,单击再恢复原来的样子.IOS的播放器有两种,MPMoviePlayerController,AVAudioPlaye ...

  7. IOS 集成 Bilibili IJKPlayer播放器,播放rtmp视频流

    因为公司项目需要,我一个连iPhone都没用过的人竟然跑去开发iOS APP.近一段时间一直忙于赶项目,到今天差不多了,所以记录一下当时遇到的各种坑,先从ios 集成 ijkplayer播放器说起! ...

  8. 利用Docker挂载Nginx-rtmp(服务器直播流分发)+FFmpeg(推流)+Vue.js结合Video.js(播放器流播放)来实现实时网络直播

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_75 众所周知,在视频直播领域,有不同的商家提供各种的商业解决方案,其中比较靠谱的服务商有阿里云直播,腾讯云直播,以及又拍云和网易云 ...

  9. 解决Ubuntu14.04下Clementine音乐播放器不能播放wma文件的问题

    参考:Ubuntu 14.04 安装深度音乐的方法 问题描述:播放wma文件时提示"GStreamer插件未安装". 解决方法:安装gstreamer-ffmpeg插件即可解决问题 ...

随机推荐

  1. 【数论】【原根】【动态规划】【bitset】2017四川省赛 K.2017 Revenge

    题意: 给你n(不超过200w)个数,和一个数r,问你有多少种方案,使得你取出某个子集,能够让它们的乘积 mod 2017等于r. 2017有5这个原根,可以使用离散对数(指标)的思想把乘法转化成加法 ...

  2. Problem E: 调用函数,整数逆序输出

    #include<stdio.h> int reverse(int number)//定义函数 { ;//result用于储存结果 ) { result=result*; i=number ...

  3. 最简单的flask表单登录

    from flask import Flask from flask import request app = Flask(__name__) @app.route('/', methods=['GE ...

  4. mysql错误10060

    setenforce 0 service iptables stop mysql -u root -p Aaa111222333 GRANT ALL PRIVILEGES ON *.* TO 'roo ...

  5. 将WPF版的弹幕播放器给优化了一下

    年前较闲的时候研究了一下WPF的性能优化,练手的时将之前写的弹幕播放器给重新写了一下.年前的时间不大够,没有写完,这两天接着弄了一下,基本上弄得差不多了. 主要重写了底层的渲染算法,优化后效果还是非常 ...

  6. Java并发包之闭锁/栅栏/信号量(转)

    本文转自http://blog.csdn.net/u010942020/article/details/79352560 感谢作者 一.Java多线程总结: 描述线程的类:Runable和Thread ...

  7. Gulp新手入门教程

    Gulp 是一个自动化工具,前端开发者可以使用它来处理常见任务: 搭建web服务器 文件保存时自动重载浏览器 使用预处理器如Sass.LESS 优化资源,比如压缩CSS.JavaScript.压缩图片 ...

  8. Mybatis数据库操作的返回值

    mybatis配置 <!-- 配置mybatis --> <bean id="sqlSessionFactory" class="org.mybatis ...

  9. fragment shader的优化

    ALU: 浮点数精度 选择性降低 shader 指令数 替换一些计算减小指令sqrt, sin, cos, recip 光照 计算用lightmap(用memory sample换计算) vertex ...

  10. Ajax的简单总结

    1. Ajax的优势和不足 1.1 Ajax的优势 1. 不需要插件支持 Ajax不需要任何浏览器插件,就可以被绝大多数主流浏览器所支持,用户只需要允许JavaScript在浏览器上执行即可. 2. ...