Platforms to show: All Mac Windows Linux Cross-Platform

/AVFoundation/Overlay video track with picture


Required plugins for this example: MBS AVFoundation Plugin, MBS Util Plugin, MBS MacCG Plugin, MBS MacCF Plugin, MBS Main Plugin, MBS MacBase Plugin

You find this example project in your Plugins Download as a Xojo project file within the examples folder: /AVFoundation/Overlay video track with picture

This example is the version from Tue, 24th Sep 2018.

Project "Overlay video track with picture.xojo_binary_project"
Class App Inherits Application
Const kEditClear = "&Delete"
Const kFileQuit = "&Quit"
Const kFileQuitShortcut = ""
EventHandler Sub Open() AVEvents = new MyAVFoundationMBS End EventHandler
Property AVEvents As MyAVFoundationMBS
End Class
MenuBar MainMenuBar
MenuItem FileMenu = "&File"
MenuItem FileQuit = "#App.kFileQuit"
MenuItem EditMenu = "&Edit"
MenuItem EditUndo = "&Undo"
MenuItem EditSeparator1 = "-"
MenuItem EditCut = "Cu&t"
MenuItem EditCopy = "&Copy"
MenuItem EditPaste = "&Paste"
MenuItem EditClear = "#App.kEditClear"
MenuItem EditSeparator2 = "-"
MenuItem EditSelectAll = "Select &All"
End MenuBar
Class MainWindow Inherits Window
Control SelectVideoFileButton Inherits PushButton
ControlInstance SelectVideoFileButton Inherits PushButton
EventHandler Sub Action() dim f as FolderItem = GetOpenFolderItem(MovieFileTypes.All) if f<>Nil then dim a as AVURLAssetMBS = AVURLAssetMBS.URLAssetWithFile(F) if a<>Nil then VideoFilePath.Text = f.DisplayName InputVideoFile = f InputVideoAsset = a end if end if SaveMovieButton.Enabled = InputImage <> nil and InputVideoAsset <> nil End EventHandler
End Control
Control SelectPictureFileButton Inherits PushButton
ControlInstance SelectPictureFileButton Inherits PushButton
EventHandler Sub Action() dim f as FolderItem = GetOpenFolderItem(ImageFileTypes.All) if f<>Nil then dim img as CGImageMBS = CGImageMBS.CreateImageWithFile(F) if img<>Nil then PictureFilePath.Text = f.DisplayName InputImageFile = f InputImage = img end if end if SaveMovieButton.Enabled = InputImage <> nil and InputVideoAsset <> nil End EventHandler
End Control
Control VideoFilePath Inherits Label
ControlInstance VideoFilePath Inherits Label
End Control
Control PictureFilePath Inherits Label
ControlInstance PictureFilePath Inherits Label
End Control
Control SaveMovieButton Inherits PushButton
ControlInstance SaveMovieButton Inherits PushButton
EventHandler Sub Action() dim n as string = InputVideoFile.NameWithoutExtensionMBS n = n + " copy" dim f as FolderItem = GetSaveFolderItem(MovieFileTypes.VideoXM4v, n) if f<>Nil then OutputVideoFile = f run end if End EventHandler
End Control
Control Label1 Inherits Label
ControlInstance Label1 Inherits Label
End Control
EventHandler Sub Open() #if DebugBuild then dim f as FolderItem = SpecialFolder.Desktop.Child("test.jpg") if f<>Nil then dim img as CGImageMBS = CGImageMBS.CreateImageWithFile(F) if img<>Nil then PictureFilePath.Text = f.DisplayName InputImageFile = f InputImage = img end if end if f = SpecialFolder.Desktop.Child("test.m4v") if f<>Nil then dim a as AVURLAssetMBS = AVURLAssetMBS.URLAssetWithFile(F) if a<>Nil then VideoFilePath.Text = f.DisplayName InputVideoFile = f InputVideoAsset = a end if end if SaveMovieButton.Enabled = InputImage <> nil and InputVideoAsset <> nil #endif End EventHandler
Sub run() const kCMPersistentTrackID_Invalid = 0 // load video and find tracks dim videoAsset as AVAssetMBS = InputVideoAsset dim mixComposition as AVMutableCompositionMBS = AVMutableCompositionMBS.composition dim type as string = AVFoundationMBS.AVMediaTypeVideo dim compositionVideoTrack as AVMutableCompositionTrackMBS = mixComposition.addMutableTrackWithMediaType(type, kCMPersistentTrackID_Invalid) dim clipVideoTracks() as AVAssetTrackMBS = videoAsset.tracksWithMediaType(type) dim clipVideoTrack as AVAssetTrackMBS = clipVideoTracks(0) dim error as NSErrorMBS dim timeRange as CMTimeRangeMBS = CMTimeRangeMBS.Make(CMTimeMBS.kCMTimeZero, videoAsset.duration) if not compositionVideoTrack.insertTimeRange(timeRange, clipVideoTrack, CMTimeMBS.kCMTimeZero, error) then Break end if compositionVideoTrack.preferredTransform = clipVideoTrack.preferredTransform // build layer with image dim myImage as CGImageMBS = InputImage dim layer as CALayerMBS = CALayerMBS.layer dim videoSize as CGSizeMBS = videoAsset.naturalSize layer.contents = myImage // center dim x as Double = (videoSize.Width - myImage.Width ) / 2 dim y as Double = (videoSize.Height - myImage.Height) / 2 layer.frame = CGMakeRectMBS(x, y, myImage.Width, myImage.Height) layer.opacity = 0.65 dim parentLayer as CALayerMBS = CALayerMBS.layer dim videoLayer as CALayerMBS = CALayerMBS.layer parentLayer.frame = CGMakeRectMBS(0, 0, videoSize.width, videoSize.height) videoLayer.frame = CGMakeRectMBS(0, 0, videoSize.width, videoSize.height) parentLayer.addSublayer videoLayer parentLayer.addSublayer Layer // Now we are creating the composition and add the instructions to insert the layer: dim videoComp as AVMutableVideoCompositionMBS = AVMutableVideoCompositionMBS.mutableVideoComposition videoComp.renderSize = videoSize videoComp.frameDuration = CMTimeMBS.Make(1, 30) videoComp.animationTool = AVVideoCompositionCoreAnimationToolMBS.videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer(videoLayer, parentLayer) /// instruction dim instruction as AVMutableVideoCompositionInstructionMBS = AVMutableVideoCompositionInstructionMBS.videoCompositionInstruction instruction.timeRange = CMTimeRangeMBS.Make(CMTimeMBS.kCMTimeZero, mixComposition.duration) dim videoTracks() as AVAssetTrackMBS = mixComposition.tracksWithMediaType(type) dim videoTrack as AVAssetTrackMBS = videoTracks(0) dim layerInstruction as AVMutableVideoCompositionLayerInstructionMBS = AVMutableVideoCompositionLayerInstructionMBS.videoCompositionLayerInstructionWithAssetTrack(videoTrack) instruction.setLayerInstructions array(layerInstruction) videoComp.setInstructions array(instruction) // add audio back dim clipAudioTracks() as AVAssetTrackMBS = videoAsset.tracksWithMediaType(AVFoundationMBS.AVMediaTypeAudio) dim clipAudioTrack as AVAssetTrackMBS = clipAudioTracks(0) dim compositionAudioTrack as AVMutableCompositionTrackMBS = mixComposition.addMutableTrackWithMediaType(AVFoundationMBS.AVMediaTypeAudio, kCMPersistentTrackID_Invalid) if not compositionAudioTrack.insertTimeRange(timeRange, clipAudioTrack, CMTimeMBS.kCMTimeZero, error) then Break end if // export dim pw as new ProgressWindow pw.info.Text = "Writing "+OutputVideoFile.name assetExport = new AVAssetExportSessionMBS(mixComposition, AVAssetExportSessionMBS.AVAssetExportPresetAppleM4VWiFi) assetExport.videoComposition = videoComp if InputVideoFile.Exists then InputVideoFile.Delete end if assetExport.outputFileType = AVFoundationMBS.AVFileTypeAppleM4V assetExport.outputFile = OutputVideoFile assetExport.shouldOptimizeForNetworkUse = true pw.assetExport = assetExport pw.show assetExport.exportAsynchronously pw End Sub
Property InputImage As CGImageMBS
Property InputImageFile As FolderItem
Property InputVideoAsset As AVURLAssetMBS
Property InputVideoFile As FolderItem
Property OutputVideoFile As FolderItem
Property assetExport As AVAssetExportSessionMBS
End Class
Class MyAVFoundationMBS Inherits AVFoundationMBS
EventHandler Sub exportAsynchronouslyCompleted(ExportSession as AVAssetExportSessionMBS, tag as variant) dim pw as ProgressWindow = tag pw.close dim f as FolderItem = ExportSession.outputFile if f<>Nil then f.Launch(True) end if End EventHandler
End Class
ImageFileTypes
Filetype image/jpeg
Filetype image/png
Filetype image/tiff
End ImageFileTypes
MovieFileTypes
Filetype video/quicktime
Filetype video/mpeg
Filetype video/mp4
Filetype video/x-m4v
Filetype video/avi
End MovieFileTypes
Class ProgressWindow Inherits Window
Control Info Inherits Label
ControlInstance Info Inherits Label
End Control
Control ProgressBar1 Inherits ProgressBar
ControlInstance ProgressBar1 Inherits ProgressBar
End Control
Control Timer1 Inherits Timer
ControlInstance Timer1 Inherits Timer
EventHandler Sub Action() dim p as integer = 100 * assetExport.progress if ProgressBar1.Value <> p then ProgressBar1.Maximum = 100 ProgressBar1.Value = p end if End EventHandler
End Control
Property assetExport As AVAssetExportSessionMBS
End Class
End Project

The items on this page are in the following plugins: MBS AVFoundation Plugin.


The biggest plugin in space...