Re: Playing AVI and MPEG using MCI

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance




"Dennis" <Dennis@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:7D683BA2-0035-401C-B6A5-1F0734CB05BB@xxxxxxxxxxxxxxxx
> Hello,
> Im writing an application to play videos using MCI. I want to open and
play
> MPEG and AVI videofiles at one time.
> I can open Avi OR MPEG at one time, but not at the same time. Im using the
> next code:
>
> AVI:
>
> '#####################################################
> Last$ = frmMain.hWnd & " Style " & &H40000000
> 'ToDo$ = "open " & ShortName1 & " Type AVIVideo Alias video1 parent " &
Last$
> i = mciSendString(ToDo$, 0&, 0, 0)
> i = mciSendString("Where video1 destination", ByVal sReturn,
Len(sReturn) -
> 1, 0)
> i = mciSendString("put video1 window at 100 81 820 570", 0&, 0, 0)
> '#####################################################
>
> MPEG
>
> '#####################################################
> Last$ = frmMain.hWnd & " Style " & &H40000000
> 'ToDo$ = "open " & ShortName1 & " Type MPEGVideo Alias video1 parent " &
Last$
> i = mciSendString(ToDo$, 0&, 0, 0)
> i = mciSendString("Where video1 destination", ByVal sReturn,
Len(sReturn) -
> 1, 0)
> i = mciSendString("put video1 window at 100 81 820 570", 0&, 0, 0)
> '#####################################################
>
> Can someone help me with this??


What you're doing is setting a parent window for the default container
window that MCI automatically creates. What you need to do is specify a
container window that MCI should use INSTEAD of its own default container
window. What I would recommend is that you create 2 pictureboxes and use
those for the container window. To do this, use the MCI "window" command
string. Here's an example that also sizes the window to accomodate the
video's dimensions and sets up a horizontal scrollbar.

NOTE: This is very old VB3 code (which is why it doesn't use, for example,
intrinsic constants). I just quickly changed a couple things to get it to
"work" in VB6.

Add a picturebox, horizontal scrollbar, and 2 command buttons to a form.
Name the picbox 'picDisplay' and make it a control array by assigning 0 to
its Index property. Name the scrollbar 'hsbVideo'. Name the command buttons
'cmdPlay' and 'cmdStop'. As written, it plays the same video in a second
picturebox. You shouldn't have much trouble modifying this code to suit
your specific needs.



-----BEGIN CODE

Option Explicit

Private Declare Function mciSendString Lib "winmm.dll" Alias
"mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As
String, ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long
Private Declare Function mciGetErrorString Lib "winmm.dll" Alias
"mciGetErrorStringA" (ByVal dwError As Long, ByVal lpstrBuffer As String,
ByVal uLength As Long) As Long
Private Declare Function GetShortPathName Lib "kernel32" Alias
"GetShortPathNameA" (ByVal lpszLongPath As String, ByVal lpszShortPath As
String, ByVal cchBuffer As Long) As Long

Dim mlRet As Long
Dim msErrBuffer As String * 255
Dim msBuffer As String * 255
Dim msStatus As String 'MCI status string
Dim mnErrRet As Integer

Dim mbStopPlayback As Integer

Const BUFFERSIZE = 255

'Constants to identify the picture boxes
Const LEFTWINDOW = 0
Const RIGHTWINDOW = 1

Private Function GetShortName(FileName As String) As String

Dim sBuffer As String
Dim lBufferLen As Long
Dim lRet As Long

sBuffer = String$(260, 0)
lRet = GetShortPathName(FileName, sBuffer, 260)
If lRet Then
GetShortName = Left$(sBuffer, InStr(sBuffer, vbNullChar) - 1)
End If

End Function

Private Sub CenterObject(obj As Control, frm As Form)

'Centers a control inside a form
obj.Left = (frm.ScaleWidth - obj.Width) \ 2
obj.Top = (frm.ScaleHeight - obj.Height) \ 2

End Sub

Private Sub cmdPlay_Click()

Dim nNullPos As Integer

'Reset the scroll bar, if necessary
If hsbVideo.Value >= hsbVideo.Max Then
hsbVideo.Value = 0
End If

'play the file in both pic boxes
mlRet = mciSendString("play LeftWindowAlias from" &
Str$(hsbVideo.Value), vbNullString, 0, 0)
If mlRet <> 0 Then
DisplayError
Exit Sub
End If

'The second video tends to start 1 or 2 frames behind so compensate by
adding 1 or 2
'to the "from" flag. How many frames behind depends on the size, length
and quality
'of the video. You'll need to experiment with this.
mlRet = mciSendString("play RightWindowAlias from" & Str$(hsbVideo.Value
+ 1), vbNullString, 0, 0)
If mlRet <> 0 Then
DisplayError
'Exit Sub
End If

Do Until mbStopPlayback
cmdStop.Enabled = True
cmdPlay.Enabled = False

'Calling the function with this command will return the
'status of the device (playing, stopped, paused, etc.)
'In order for this call to work properly,
'msBuffer must be a fixed-length string
mlRet = mciSendString("status LeftWindowAlias mode", msBuffer,
BUFFERSIZE, Me.hWnd)
If mlRet <> 0 Then
DisplayError
End If
msStatus = msBuffer
If InStr(msStatus, "stopped") Then
Exit Do
End If

If mbStopPlayback = False Then
'Get the video's current position
mlRet = mciSendString("status LeftWindowAlias position",
msBuffer, BUFFERSIZE, Me.hWnd)
nNullPos = InStr(msBuffer, Chr$(0))
On Error Resume Next
hsbVideo.Value = CInt(Left$(msBuffer, nNullPos - 1))
On Error GoTo 0
End If

DoEvents 'yield to windows
Loop

'reset the flag
mbStopPlayback = False

cmdStop.Enabled = False
cmdPlay.Enabled = True

End Sub

Private Sub cmdStop_Click()

'stop playback
mlRet = mciSendString("stop LeftWindowAlias", vbNullString, 0, 0)
mlRet = mciSendString("stop RightWindowAlias", vbNullString, 0, 0)
If mlRet <> 0 Then
DisplayError
End If

End Sub

Private Sub DisplayError()

mnErrRet = mciGetErrorString(mlRet, msErrBuffer, BUFFERSIZE)
If mnErrRet = 1 Then
MsgBox msErrBuffer, 48, "MCI Error"
Else
MsgBox "An unknown error occured", 16, "Error"
End If

End Sub

Private Sub Form_Load()

cmdStop.Enabled = False

'Create 2nd instance of picture box
Load picDisplay(RIGHTWINDOW)
Me.Show: DoEvents

'Path is hard-coded for example purposes only
Call LoadAVI("D:\Example Source Code\Visual Basic\jbird5.avi")

End Sub

Private Sub Form_Unload(Cancel As Integer)

'Make sure all devices and resources have been freed.
'This is imperative, or else you may receive MCI errors.
mlRet = mciSendString("close all wait", vbNullString, 0, 0)

End Sub

Private Sub GetDimensions(sSource As String, iWidth As Integer, iHeight As
Integer)

ReDim sTemp(4) As String
Dim iCounter As Integer
Dim nSpace As Integer
Dim nSpace2 As Integer

iCounter = 1
nSpace = InStr(nSpace + 1, sSource, " ")
sTemp(iCounter) = Left$(sSource, nSpace - 1)
Do
iCounter = iCounter + 1
nSpace2 = InStr(nSpace + 1, sSource, " ")
If nSpace2 = 0 Then nSpace2 = Len(sSource) + 1
sTemp(iCounter) = Mid$(sSource, nSpace + 1, nSpace2 - nSpace - 1)
nSpace = InStr(nSpace + 1, sSource, " ")
Loop Until nSpace = 0

iWidth = CInt(sTemp(3))
iHeight = CInt(sTemp(4))

End Sub

Private Sub hsbVideo_Change()

'Need to determine whether to step forwards or backwards,
'and how many frames to step.

'This requires comparing the scroll bar's previous value
'to its current value to determine the direction, and then
'taking the difference between the 2 to determine the
'number of frames.

Static stiPrevVal As Integer

If InStr(msStatus, "playing") = 0 Then
If hsbVideo.Value > stiPrevVal Then
mlRet = mciSendString("step LeftWindowAlias by" &
Str$(hsbVideo.Value - stiPrevVal), vbNullString, 0, 0)
mlRet = mciSendString("step RightWindowAlias by" &
Str$(hsbVideo.Value - stiPrevVal), vbNullString, 0, 0)
If mlRet <> 0 Then DisplayError
Else
mlRet = mciSendString("step LeftWindowAlias by" &
Str$(Abs(hsbVideo.Value - stiPrevVal)) & " reverse", vbNullString, 0, 0)
mlRet = mciSendString("step RightWindowAlias by" &
Str$(Abs(hsbVideo.Value - stiPrevVal)) & " reverse", vbNullString, 0, 0)
End If
End If

stiPrevVal = hsbVideo.Value

End Sub

Private Function LoadAVI(ByVal sAVIFile As String) As Boolean

Dim iFrames As Integer
Dim iNull As Integer
Dim sRect As String
Dim iWidth As Integer
Dim iHeight As Integer
Dim sCaption As String

Me.MousePointer = vbHourglass

'Make sure no file is currently open
mlRet = mciSendString("close all wait", vbNullString, 0, 0)

'MCI won't always work properly with long file names, so always
'get the short name
sAVIFile = GetShortName(sAVIFile)
If Len(sAVIFile) = 0 Then
LoadAVI = False
Exit Function
End If

'Open the device
mlRet = mciSendString("open " & sAVIFile & " alias LeftWindowAlias
wait", vbNullString, 0, 0)
If mlRet <> 0 Then
'An error occurred opening the device. IF the device could not be
'opened, no other commands will work. Exit the sub and leave the
'Play button disabled.
DisplayError
Exit Function
End If

'Enable the Play button
cmdPlay.Enabled = True

'Set picturebox as the display container.
mlRet = mciSendString("window LeftWindowAlias handle" &
Str$(picDisplay(LEFTWINDOW).hWnd) & " wait", vbNullString, 0, 0)
If mlRet <> 0 Then
'If an error occurred, MCI will create and manage a window itself
DisplayError
End If

'Get the video's resolution
mlRet = mciSendString("where LeftWindowAlias source wait", msBuffer,
BUFFERSIZE, 0)
If mlRet <> 0 Then
DisplayError
End If
iNull = InStr(msBuffer, Chr$(0))
sRect = Left$(msBuffer, iNull - 1)
Call GetDimensions(sRect, iWidth, iHeight)

'Size the picture box to match the video
picDisplay(LEFTWINDOW).Width = (iWidth * Screen.TwipsPerPixelX) +
(picDisplay(LEFTWINDOW).Width - picDisplay(LEFTWINDOW).ScaleWidth)
picDisplay(LEFTWINDOW).Height = (iHeight * Screen.TwipsPerPixelY) +
(picDisplay(LEFTWINDOW).Height - picDisplay(LEFTWINDOW).ScaleHeight)

'Center the picture box (optional)
'Call CenterObject(picDisplay, Form1)

'Size and position the scroll bar
hsbVideo.Left = picDisplay(LEFTWINDOW).Left
hsbVideo.Width = picDisplay(LEFTWINDOW).Width
hsbVideo.Top = picDisplay(LEFTWINDOW).Top +
picDisplay(LEFTWINDOW).Height

'This command will tell you the number of frames in the video. Use
'this to set the Max property of the scroll bar.
mlRet = mciSendString("status LeftWindowAlias length wait", msBuffer,
BUFFERSIZE, 0)
If mlRet <> 0 Then
DisplayError
End If
iNull = InStr(msBuffer, Chr$(0))
iFrames = CInt(Left$(msBuffer, iNull - 1))
hsbVideo.Min = 0
hsbVideo.Max = iFrames
hsbVideo.Value = 0

'Call routine to load video in second picture box
Call LoadInPicBox2(sAVIFile)

Me.MousePointer = vbDefault

LoadAVI = True

End Function

Private Sub LoadInPicBox2(ByVal sAVIFile As String)

'Set properties of 2nd box to match first
picDisplay(RIGHTWINDOW).Height = picDisplay(LEFTWINDOW).Height
picDisplay(RIGHTWINDOW).Width = picDisplay(LEFTWINDOW).Width
picDisplay(RIGHTWINDOW).Top = picDisplay(LEFTWINDOW).Top

'Position the 2nd pic box
picDisplay(RIGHTWINDOW).Left = picDisplay(LEFTWINDOW).Left +
picDisplay(LEFTWINDOW).Width + 200

'Make the 2nd pic box visible
picDisplay(RIGHTWINDOW).Visible = True

'Resize the form. Depending on your screen resolution, you may have
'to alter this code or move the pic boxes around some.
Me.Width = picDisplay(LEFTWINDOW).Width * 2 + 1000

'Open the device using an alternate alias
mlRet = mciSendString("open " & sAVIFile & " alias RightWindowAlias
wait", vbNullString, 0, 0)
If mlRet <> 0 Then
DisplayError
Exit Sub
End If

'Set picturebox as the display container.
mlRet = mciSendString("window RightWindowAlias handle" &
Str$(picDisplay(RIGHTWINDOW).hWnd) & " wait", vbNullString, 0, 0)
If mlRet <> 0 Then
'If an error occurred, MCI will create and manage a window itself
DisplayError
End If

End Sub

-----END CODE


--
Mike
Microsoft MVP Visual Basic


.


Quantcast