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。


本文转自over140 51CTO博客,原文链接:http://blog.51cto.com/over140/586632,如需转载请自行联系原作者

相关文章
音视频开发: ffmpeg采集桌面屏幕、摄像头保存为视频
音视频开发: ffmpeg采集桌面屏幕、摄像头保存为视频
823 0
音视频开发: ffmpeg采集桌面屏幕、摄像头保存为视频
|
7月前
|
JavaScript API
uniapp实现录音功能和播放功能
uniapp实现录音功能和播放功能
|
3月前
|
编解码
音视频录制播放原理
音视频录制播放原理
63 1
|
3月前
|
Windows
使用ffmpeg调用电脑自带的摄像头和扬声器录制音视频
使用ffmpeg调用电脑自带的摄像头和扬声器录制音视频
|
4月前
uniapp制作录音播放功能
uniapp制作录音播放功能
71 0
|
5月前
|
存储 Cloud Native Linux
音视频 ffplay播放控制
音视频 ffplay播放控制
|
7月前
|
Ubuntu Linux 人机交互
快速实现摄像头视频画面的远程预览
通过阿里云生活物联网平台的智能视频服务Link Visual来快速的搭建并实现摄像头视频画面的远程预览功能。
146 0
|
8月前
|
前端开发 JavaScript
uniapp 录音和播放功能
uniapp 录音和播放功能
219 0
|
安全 JavaScript 前端开发
如何让在线视频以自定义速度播放
现在看视频不来个两倍速(或者更快)都觉得在浪费生命。 特别是在看视频教程的时候,文字我们可以做到一目十行,但是视频呢,如果有字幕,我们甚至不用听清,用3倍速或者4倍速完全没有问题,尤其在看别人在线写代码的时候,速度快了,就觉得特别顺滑。
389 0
如何让在线视频以自定义速度播放