程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#視頻監控系列(13):H264播放器——控制播放和截圖

C#視頻監控系列(13):H264播放器——控制播放和截圖

編輯:關於C#

一、控制播放

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代碼說明:

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。

結束

現在在做語音部分,受阻中...

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved