McBasic™Get McBasic™ ↗
Build 881
Hands-on tutorial · Media & graphics

Control video playback

Build a video surface with honest loading and error feedback.

1 Form / control designs1 complete BASIC filesGuided sample project

Video playback has asynchronous state transitions even when the file is local. Keep the source declaration with the project, preserve aspect behavior and react to Failed explicitly. Test the built application as well as the IDE run path.

Step 1Prepare a safe practice project#

Extract the archive into a new writable folder, separate from your own application. Open VideoPlayer.mcbproj in McBasic™. Keep every declared source, layout, resource and migration file together.

To reconstruct it yourself, create a DesktopApp project and add the files declared below. In the complete project, follow these steps as a guided rebuild: replace each named source file once and Check after all its procedures are present.

Exact project configuration
project.mcproj
{
  "schemaVersion": 1,
  "projectId": "6cb06642-8475-42ed-9154-e80282784d2f",
  "name": "VideoPlayerSample",
  "kind": "DesktopApp",
  "ai": {
    "storeChatsInProject": false
  },
  "language": {
    "dialect": "McBasic1",
    "requireExplicit": true,
    "compare": "Binary",
    "defaultArrayBase": 0
  },
  "application": {
    "bundleIdentifier": "com.mcbasic.samples.videoplayer",
    "version": "0.1.0",
    "buildNumber": "1",
    "startupFormId": "form-main",
    "shutdownMode": "OnStartupFormClosed"
  },
  "forms": [
    {
      "id": "form-main",
      "typeName": "frmMain",
      "layout": "Forms/frmMain.form.json",
      "code": "Forms/frmMain.bas"
    }
  ],
  "modules": [],
  "classes": [],
  "tests": [],
  "references": [],
  "resources": [
    {
      "name": "DemoVideo",
      "path": "Resources/demo.mp4"
    }
  ],
  "targets": [
    "osx-arm64"
  ],
  "capabilities": []
}

Step 2Build the Form and set its properties#

frmMain

Select the Form first and set its properties. Add containers before their children. These are initial Designer values, not statements to paste into a procedure.

Form propertyValue
Caption"VideoPlayer — McBasic"
Width700
Height510
MinWidth560
MinHeight400
TypeNameParent
VideoPlayervidDemoForm
CommandButtoncmdPlayForm
CommandButtoncmdPauseForm
CommandButtoncmdStopForm
CommandButtoncmdReloadForm
LabellblStatusForm
vidDemo · exact Inspector values
PropertyValue
Left24
Top24
Width652
Height320
Source"DemoVideo"
AutoPlayFalse
LoopFalse
Volume0.4
ControlsVisibleTrue
Stretch"Uniform"
Anchor edgesLeft, Top, Right, Bottom
cmdPlay · exact Inspector values
PropertyValue
Left24
Top362
Width110
Height36
Caption"Play"
Anchor edgesLeft, Bottom
cmdPause · exact Inspector values
PropertyValue
Left146
Top362
Width110
Height36
Caption"Pause"
Anchor edgesLeft, Bottom
cmdStop · exact Inspector values
PropertyValue
Left268
Top362
Width110
Height36
Caption"Stop"
Anchor edgesLeft, Bottom
cmdReload · exact Inspector values
PropertyValue
Left390
Top362
Width110
Height36
Caption"Reload"
Anchor edgesLeft, Bottom
lblStatus · exact Inspector values
PropertyValue
Left24
Top414
Width652
Height36
Caption"Loading"
Anchor edgesLeft, Right, Bottom

Step 3Connect the events explicitly#

frmMain

ObjectEventProcedureParameters
vidDemoLoadedvidDemo_LoadedLoaded()
vidDemoCompletedvidDemo_CompletedCompleted()
vidDemoFailedvidDemo_FailedFailed()
vidDemoStateChangedvidDemo_StateChangedStateChanged()
cmdPlayClickcmdPlay_ClickClick()
cmdPauseClickcmdPause_ClickClick()
cmdStopClickcmdStop_ClickClick()
cmdReloadClickcmdReload_ClickClick()
FormLoadForm_Load()

Step 4Enter the complete behavior#

Open the named source file. Enter declarations first, then every procedure. Expand a procedure for its full body, or copy the complete file. Helpers are required: do not stop after entering the first Click handler.

Forms/frmMain.bas

Enter these declarations at file scope, before the procedures.

Forms/frmMain.bas · declarations
Option Explicit
Private Sub Form_Load()

Initialize state before enabling dependent actions. Keep the shared declarations and startup dependencies with this procedure.

Forms/frmMain.bas · Form_Load
Private Sub Form_Load()
    lblStatus.Caption = "Video state: " + vidDemo.State
End Sub
Private Sub cmdPlay_Click()

Enter the complete action, including its input checks and calls to helper procedures.

Forms/frmMain.bas · cmdPlay_Click
Private Sub cmdPlay_Click()
    If vidDemo.Duration > 0 Then
        vidDemo.Position = 0
    End If
    vidDemo.Play
End Sub
Private Sub cmdPause_Click()

Enter the complete action, including its input checks and calls to helper procedures.

Forms/frmMain.bas · cmdPause_Click
Private Sub cmdPause_Click()
    vidDemo.Pause
End Sub
Private Sub cmdStop_Click()

Enter the complete action, including its input checks and calls to helper procedures.

Forms/frmMain.bas · cmdStop_Click
Private Sub cmdStop_Click()
    vidDemo.Stop
End Sub
Private Sub cmdReload_Click()

Enter the complete action, including its input checks and calls to helper procedures.

Forms/frmMain.bas · cmdReload_Click
Private Sub cmdReload_Click()
    vidDemo.Load
End Sub
Private Sub vidDemo_Loaded()

Enter this helper in the named source file, outside every other procedure. Its callers are included in the same project.

Forms/frmMain.bas · vidDemo_Loaded
Private Sub vidDemo_Loaded()
    lblStatus.Caption = "Loaded " + vidDemo.Source + " (" + CStr(vidDemo.Duration) + " s)"
End Sub
Private Sub vidDemo_Completed()

Enter this helper in the named source file, outside every other procedure. Its callers are included in the same project.

Forms/frmMain.bas · vidDemo_Completed
Private Sub vidDemo_Completed()
    lblStatus.Caption = "Playback completed"
End Sub
Private Sub vidDemo_Failed()

Enter this helper in the named source file, outside every other procedure. Its callers are included in the same project.

Forms/frmMain.bas · vidDemo_Failed
Private Sub vidDemo_Failed()
    lblStatus.Caption = vidDemo.Error
End Sub
Private Sub vidDemo_StateChanged()

Enter this helper in the named source file, outside every other procedure. Its callers are included in the same project.

Forms/frmMain.bas · vidDemo_StateChanged
Private Sub vidDemo_StateChanged()
    lblStatus.Caption = "Video state: " + vidDemo.State
    If vidDemo.Playing Then
        lblStatus.Caption = lblStatus.Caption + " at " + CStr(vidDemo.Position) + " s"
    ElseIf vidDemo.Paused Then
        lblStatus.Caption = "Paused at " + CStr(vidDemo.Position) + " s"
    End If
End Sub
Copy the complete Forms/frmMain.bas file

Replace the file once; do not append duplicate procedures.

Forms/frmMain.bas
Option Explicit

Private Sub Form_Load()
    lblStatus.Caption = "Video state: " + vidDemo.State
End Sub

Private Sub cmdPlay_Click()
    If vidDemo.Duration > 0 Then
        vidDemo.Position = 0
    End If
    vidDemo.Play
End Sub

Private Sub cmdPause_Click()
    vidDemo.Pause
End Sub

Private Sub cmdStop_Click()
    vidDemo.Stop
End Sub

Private Sub cmdReload_Click()
    vidDemo.Load
End Sub

Private Sub vidDemo_Loaded()
    lblStatus.Caption = "Loaded " + vidDemo.Source + " (" + CStr(vidDemo.Duration) + " s)"
End Sub

Private Sub vidDemo_Completed()
    lblStatus.Caption = "Playback completed"
End Sub

Private Sub vidDemo_Failed()
    lblStatus.Caption = vidDemo.Error
End Sub

Private Sub vidDemo_StateChanged()
    lblStatus.Caption = "Video state: " + vidDemo.State
    If vidDemo.Playing Then
        lblStatus.Caption = lblStatus.Caption + " at " + CStr(vidDemo.Position) + " s"
    ElseIf vidDemo.Paused Then
        lblStatus.Caption = "Paused at " + CStr(vidDemo.Position) + " s"
    End If
End Sub

Step 5Keep resources and storage reproducible#

Keep the following files at their declared relative paths. Apply migrations before the first query. Media and report resources must travel with the build.

FilePurpose
Resources/demo.mp4Bundled asset / license

Step 6Check, run and test the result#

Save all files and run Check. Resolve diagnostics before Run. Developer CLI users can work from the extracted folder:

Developer CLI
mcbasic check VideoPlayer.mcbproj
mcbasic run VideoPlayer.mcbproj

Acceptance checklist

  • Load and play the sample video.
  • Pause and resume, then stop.
  • Reload the asset.
  • Run the built app and verify the video resource is present.

Step 7Make one change and repeat the tests#

Add a loading label that is cleared by Loaded and replaced by an error on Failed.

Save a working Git checkpoint first. Change one behavior, Check again and repeat the acceptance checklist. Compare with the downloaded solution if a regression appears.

Source baseline 20f4bfed6b · Build manifest