我按照DX8SDK示例的方法,用ActiveMovie control type library在一个图象框中播放视频,然后再这个图象框中绘制其他内容,但最后得到的结果完全不正确,请问高手应该怎么解决

解决方案 »

  1.   

    为了是说明如何在VB中利用ActiveMovie Control type library实现流媒体的播放,下面给出了一个名为VBDemo的项目实现代码,该程序可以以不同的速率来播放wav、avi、mepg等多种格式的多媒体文件,同时显示多媒体文件的长度、播放速率等信息。 在这个项目的窗体上定义一个FILE(名字为mnu_File)的主菜单,它包含OPEN(名字为mnu_FileOpen)和EXIT(名字为mnu_FileExit)子菜单,分别用于打开流媒体文件和退出应用程序;工具条tbControlBar上定义三个按钮,分别为实现流媒体的"播放"、"暂停"、"停止"功能的按钮;名为picVideoWindow的PictureBox控件用来作为播放流媒体视频数据的容器;slBanlance和slVolume两个Slider控件分别用来控制媒体流的声音大小和平衡度,它们的最大最小值分别为(-10000,0)和(-5000,5000);在界面的信息栏中,txtDuration和txtBox这两个TextBox控件分别用来显示正在播放的流媒体的时间长度和播放速率;关于播放速率,用户可以通过optplaybackR单选框来选择正常播放、两倍速率播放还是半速播放。程序编译后的界面如下(抱歉,使用考屏的方法无法将播放的图像一同考贝下来):
      

  2.   

    程序的主要实现思路是在调用了Windows\System下动态链接库Quatrz.dll的基础上,定义一个全局的Object对象m_objMediaControl,令m_objMediaControl指向FilgraphManager的一个新实例,调用它的RenderFile函数装载需要播放的流媒体文件,然后使用Run等函数就可以实现各种播放功能了;为了将流媒体的语音效果准确的显示出来,需要再定义一个IbasicAudio音频对象m_objBasicAudio,用来提取流媒体的音频数据并控制语音的大小,IMediaPosition 对象m_objMediaPosition是用来为多媒体文件定位的。最后显示流媒体时需要打开一个播放Video的窗口,可以将picVideoWindow的句柄hWnd赋给的m_objVideoWindow的Owner属性 ,这样picVideoWindow就可以显示接收的多媒体数据流了。具体实现代码如下: ******************************************************************
    为了处理多媒体流,定义以下全局变量.
    *******************************************************************Option Explicit
    Private m_dblRate As Double '多媒体流播放的幀速率,也既是每秒播放的幀数;
    Private m_bstrFileName As String '需要播放的流媒体文件名;
    Private m_dblRunLength As Double '播放的流媒体的持续时间,单位为秒;
    Private m_dblStartPosition As Double '待播放的流媒体文件的初始位置,以秒为单位;
    Private m_boolVideoRunning As Boolean '多媒体流正在播放的标志;
    Private m_objBasicAudio As IBasicAudio 'Basic 的音频对象,用来处理媒体流中的语音数据;
    Private m_objVideoWindow As IVideoWindow '视频窗口对象;
    Private m_objFilgraphManager As FilgraphManager '媒体控制对象;
    Private m_objMediaPosition As IMediaPosition '媒体位置对象; ********************************************************************************
    * 窗体加载时作一些初始化工作
    ********************************************************************************
    Private Sub Form_Load()
    On Local Error GoTo ErrLine
    optPlaybackRate(1).Value = True '回放速率设置为正常;
    frmMain.ScaleMode = 3 '窗体的坐标单位设置为像素;
    '将工具栏上的所有按钮设置为"无效"
    tbControlBar.Buttons("play").Enabled = False
    tbControlBar.Buttons("stop").Enabled = False
    tbControlBar.Buttons("pause").Enabled = False
    Exit Sub
    ErrLine:
    Err.Clear
    Exit Sub
    End Sub ***********************************************************************
    窗体卸载时清除与多媒体流相关的全局对象;
    ***********************************************************************
    Private Sub Form_Unload(Cancel As Integer)
    On Local Error GoTo ErrLine
    '停止播放;
    m_boolVideoRunning = False
    DoEvents
    If m_objFilgraphManager <>NULL Then
    m_objFilgraphManager.Stop
    End If
    '清除视频窗口;
    If m_objVideoWindow <> NULL Then
    m_objVideoWindow.Owner = 0 '设置m_objVideoWindow对象的拥有者为空;
    End If
    '清除与多媒体流相关的全局对象;
    If m_objBasicAudio <> Null Then Set m_objBasicAudio = Nothing
    If m_objBasicVideo <> NULL Then Set m_objBasicVideo = Nothing
    If m_objFilgraphManager <> NULL Then Set m_objFilgraphManager = Nothing
    If m_objVideoWindow <> NULL Then Set m_objVideoWindow = Nothing
    If m_objMediaPosition <> NULL Then Set m_objMediaPosition = Nothing
    Exit Sub
    ErrLine:
    Err.Clear
    Exit Sub
    End Sub 
      

  3.   


    ************************************************************************
    "退出"菜单响应函数;
    **************************************************************************
    Private Sub mnu_FileExit_Click()
    Dim frm As Form
    On Local Error GoTo ErrLine
    For Each frm In Forms
    frm.Move Screen.Width * 8, Screen.Height * 8
    frm.Visible = False: Unload frm
    Next
    Exit Sub
    ErrLine:
    Err.Clear
    Exit Sub
    End Sub ******************************************************************
    "文件打开"菜单响应函数;
    ******************************************************************
    Private Sub mnu_FileOpen_Click()
    Dim nCount As Long
    On Local Error GoTo ErrLine
    '清理内存,防止在此之前已经打开过一个文件;
    Call Form_Unload(True)
    '选择打开的文件类型默认为:mov、avi、mp3、mp2、wav;
    ctrlCommonDialog.Filter="MediaFiles (*.mpg;*.avi;*.mov;*.wav;*.mp2;*.mp3)|*.mpg;*.avi;*.mov;*.wav;*.mp2;*.mp3"
    ctrlCommonDialog.ShowOpen
    m_bstrFileName = ctrlCommonDialog.FileName
    '初始化一个滤波器图表
    Set m_objFilgraphManager = New FilgraphManager
    Call m_objFilgraphManager.RenderFile(m_bstrFileName) '装载流媒体文件;
    '设置Basic的音频对象,如语音的大小、平衡度等;
    Set m_objBasicAudio = m_objFilgraphManager
    m_objBasicAudio.Volume = slVolume.Value
    m_objBasicAudio.Balance = slBalance.Value
    '设置视频窗口对象,初始化位置后将其父窗口设置为窗口上的PictureBox对象;
    Set m_objVideoWindow = m_objFilgraphManager
    m_objVideoWindow.WindowStyle = CLng(&H6000000)
    m_objVideoWindow.Top = 0
    m_objVideoWindow.Left = 0
    m_objVideoWindow.Width = picVideoWindow.Width
    m_objVideoWindow.Height = picVideoWindow.Height
    m_objVideoWindow.Owner = picVideoWindow.hWnd
    '设置多媒体位置对象;
    Set m_objMediaPosition = m_objFilgraphManager
    '根据用户的选择来设置多媒体流的播放速率;
    For nCount = optPlaybackRate.LBound To optPlaybackRate.UBound
    If optPlaybackRate(nCount).Value = True Then
    Select Case nCount
    Case 0
    If m_objMediaPosition <>NULL Then _
    m_objMediaPosition.Rate = 0.5
    Case 1
    If m_objMediaPosition <>NULL Then _
    m_objMediaPosition.Rate = 1
    Case 2
    If m_objMediaPosition <> NULL Then _
    m_objMediaPosition.Rate = 2
    End Select
    Exit For
    End If
    Next
    m_dblRunLength = Round(m_objMediaPosition.Duration, 2)
    txtDuration.Text = CStr(m_dblRunLength)
    ' 设置当前位置为起始位置;
    m_dblStartPosition = 0
    ' 显示用户选择的多媒体流的播放速率;
    m_dblRate = m_objMediaPosition.Rate
    txtRate.Text = CStr(m_dblRate)
    '设置按钮的默认状态;
    tbControlBar.Buttons("play").Enabled = True
    tbControlBar.Buttons("stop").Enabled = False
    tbControlBar.Buttons("pause").Enabled = False
    Call tbControlBar_ButtonClick(tbControlBar.Buttons(1))
    ErrLine:
    Err.Clear
    Resume Next
    Exit Sub
    End Sub ************************************************************************
    用户点击播放速率单选按钮时的响应处理函数;
    ************************************************************************
    Private Sub optPlaybackRate_Click(Index As Integer)
    On Local Error GoTo ErrLine
    Select Case Index
    Case 0
    If m_objMediaPosition<> NULL Then _
    txtRate.Text = 0.5
    Case 1
    If m_objMediaPosition<> NULL Then _
    txtRate.Text = 1
    Case 2
    If m_objMediaPosition<> NULL Then _
    txtRate.Text = 2
    End Select
    '重新设置媒体回放的播放速率;
    If m_objMediaPosition Then
    Select Case Index
    Case 0
    If m_objMediaPosition <>NULL Then _
    m_objMediaPosition.Rate = 0.5
    Case 1
    If m_objMediaPosition <> NULL Then _
    m_objMediaPosition.Rate = 1
    Case 2
    If m_objMediaPosition <> NULL Then _
    m_objMediaPosition.Rate = 2
    End Select
    End If
    Exit Sub
    ErrLine:
    Err.Clear
    Exit Sub
    End Sub **************************************************************************
    音频平衡滑动条改变时的响应处理函数;
    **************************************************************************
    Private Sub slBalance_Change()
    On Local Error GoTo ErrLine
    '用户使用滑动条来设置语音平衡的值;
    If m_objFilgraphManager <> NULL Then _
    m_objBasicAudio.Balance = slBalance.Value
    Exit Sub
    ErrLine:
    Err.Clear
    Exit Sub
    End Sub ***********************************************************************
    设置音量大小的滑动条改变时的响应处理函数
    ***********************************************************************
    Private Sub slVolume_Change()
    On Local Error GoTo ErrLine
    '用户使用滑动条来设置语音的大小;
    If m_objFilgraphManager <>NULL Then _
    m_objBasicAudio.Volume = slVolume.Value
    Exit Sub
    ErrLine:
    Err.Clear
    Exit Sub
    End Sub ***************************************************************************
    界面上关于多媒体流的"播放"、"暂停"、"停止"等按钮的点击响应函数;
    ***************************************************************************
    Private Sub tbControlBar_ButtonClick(ByVal Button As Button)
    On Local Error GoTo ErrLine
    If ObjPtr(m_objMediaControl) > 0 Then
    If Button.Key = "play" Then '如果用户点击了"播放"按钮;'如果多媒体的当前位置不处在文件尾部,则对多媒体流的位置重新置位;
    If CLng(m_objMediaPosition.CurrentPosition) < CLng(m_dblStartPosition) Then
    m_objMediaPosition.CurrentPosition = m_dblStartPosition
    ElseIf CLng(m_objMediaPosition.CurrentPosition) = CLng(m_dblRunLength) Then
    m_objMediaPosition.CurrentPosition = m_dblStartPosition
    End If
    Call m_objFilgraphManager.Run
    m_boolVideoRunning = True
    tbControlBar.Buttons("play").Enabled = False
    tbControlBar.Buttons("stop").Enabled = True
    tbControlBar.Buttons("pause").Enabled = True
    picVideoWindow.Refresh
    ElseIf Button.Key = "pause" Then '用户点击了"暂停"按钮;
    Call m_objFilgraphManager.Pause
    m_boolVideoRunning = False
    tbControlBar.Buttons("play").Enabled = True
    tbControlBar.Buttons("stop").Enabled = True
    tbControlBar.Buttons("pause").Enabled = False
    ElseIf Button.Key = "stop" Then '用户点击了"停止"按钮;
    Call m_objFilgraphManager.Stop
    m_boolVideoRunning = False
    ' 重新设置视频流的当前播放位置为起始位置;
    m_objMediaPosition.CurrentPosition = 0
    txtElapsed.Text = "0.0"
    tbControlBar.Buttons("play").Enabled = True
    tbControlBar.Buttons("stop").Enabled = False
    tbControlBar.Buttons("pause").Enabled = False
    End If
    End If
    Exit Sub
    ErrLine:
    Err.Clear
    Exit Sub
    End Sub   以上内容希望对在多媒体领域有兴趣的读者朋友有所帮助,起到抛砖引玉的作用,将上面的代码稍加修改后添加到自己正在开发的应用程序中,实现流媒体的播放,达到丰富软件的功能的目的。
      

  4.   

    播放视频并没有问题,我是想在图象框m_objVideoWindow上绘制一些内容,和视频一起显示出来
      

  5.   

    请访问http://hqtech.nease.net,在文档中心有一篇文章:卡拉OK字幕叠加之简单实现
    也许和你的问题相关。
      

  6.   

    谢谢楼上走了好多书店也找不到<DirectShow开发指南>,电子版也没有……