Platforms to show: All Mac Windows Linux Cross-Platform

/AVFoundation/Add text to video


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

You find this example project in your Plugins Download as a Xojo project file within the examples folder: /AVFoundation/Add text to video

This example is the version from Fri, 26th Jul 2018.

Project "Add text to video.xojo_binary_project"
Class App Inherits Application
Const kEditClear = "&Delete"
Const kFileQuit = "&Quit"
Const kFileQuitShortcut = ""
End Class
Class Window1 Inherits Window
EventHandler Sub Open() AVFoundation = new MyAVFoundation dim VideoFile as FolderItem = SpecialFolder.Desktop.Child("test.mp4") dim OutputFile as FolderItem = SpecialFolder.Desktop.Child("output.mp4") // 1. mergeComposition adds all the AVAssets mergeComposition = new AVMutableCompositionMBS dim trackVideo as AVMutableCompositionTrackMBS = mergeComposition.addMutableTrackWithMediaType(AVFoundation.AVMediaTypeVideo, 0) // 2. Add a bank for theme insertion later //trackVideo.insertTimeRange(range, ofTrack: VideoHelper.Static.blankTrack, atTime: kCMTimeZero, error: nil) // 3. Source tracks dim sourceAsset as AVURLAssetMBS = AVURLAssetMBS.URLAssetWithFile(VideoFile) // wait for duration to become available dim e as NSErrorMBS while sourceAsset.statusOfValueForKey("duration", e) = sourceAsset.AVKeyValueStatusLoading // wait app.YieldToNextThread wend if e <> nil then MsgBox e.LocalizedDescription end if dim sourceDuration as CMTimeRangeMBS = new CMTimeRangeMBS(CMTimeMBS.kCMTimeZero, sourceAsset.duration) dim videoTracks() as AVAssetTrackMBS = sourceAsset.tracksWithMediaType(AVFoundation.AVMediaTypeVideo) dim audioTracks() as AVAssetTrackMBS = sourceAsset.tracksWithMediaType(AVFoundation.AVMediaTypeAudio) dim vtrack as AVAssetTrackMBS = videoTracks(0) dim atrack as AVAssetTrackMBS = audioTracks(0) if (vtrack = nil) then break return end if dim renderWidth as integer = vtrack.naturalSize.width dim renderHeight as integer = vtrack.naturalSize.height dim insertTime as CMTimeMBS = CMTimeMBS.kCMTimeZero dim endTime as CMTimeMBS = sourceAsset.duration dim range as CMTimeRangeMBS = sourceDuration // append tracks call trackVideo.insertTimeRange(sourceDuration, vtrack, insertTime, e) if e <> nil then MsgBox e.LocalizedDescription return end if // add video track dim trackAudio as AVMutableCompositionTrackMBS = mergeComposition.addMutableTrackWithMediaType(AVFoundation.AVMediaTypeAudio, 0) call trackAudio.insertTimeRange(sourceDuration, atrack, insertTime, e) if e <> nil then MsgBox e.LocalizedDescription return end if // 4. Add subtitles (we call it theme) dim themeVideoComposition as AVMutableVideoCompositionMBS = AVMutableVideoCompositionMBS.mutableVideoCompositionWithPropertiesOfAsset(sourceAsset) // 4.1 - Create AVMutableVideoCompositionInstruction dim mainInstruction as new AVMutableVideoCompositionInstructionMBS mainInstruction.timeRange = range // 4.2 - Create an AVMutableVideoCompositionLayerInstruction for the video track and fix the orientation. dim videolayerInstruction as AVMutableVideoCompositionLayerInstructionMBS = AVMutableVideoCompositionLayerInstructionMBS.videoCompositionLayerInstructionWithAssetTrack(trackVideo) videolayerInstruction.setTransform(trackVideo.preferredTransform, insertTime) 'videolayerInstruction.setOpacity(0.0, endTime) videolayerInstruction.setOpacity(1.0, 1.0, range) // 4.3 - Add instructions mainInstruction.setLayerInstructions array(videolayerInstruction) 'themeVideoComposition.renderScale = 1.0 themeVideoComposition.renderSize = new CGSizeMBS(renderWidth, renderHeight) themeVideoComposition.frameDuration = new CMTimeMBS(1, 30) themeVideoComposition.setInstructions array(mainInstruction) // add the theme // setup variables // add text dim r as new CGRectMBS(0, 0, renderWidth, renderHeight) dim title as string = "Testing this subtitle" dim titleLayer as new CATextLayerMBS titleLayer.string = title titleLayer.frame = r dim fontName as String = "Helvetica-Bold" dim fontSize as double = 36 titleLayer.fontSize = fontSize titleLayer.font = NSFontMBS.fontWithName(fontName, fontSize) titleLayer.alignmentMode = CATextLayerMBS.kCAAlignmentCenter titleLayer.foregroundColor = CGColorMBS.White dim backgroundLayer as new CALayerMBS backgroundLayer.frame = r backgroundLayer.masksToBounds = true // 2. set parent layer and video layer dim parentLayer as new CALayerMBS dim videoLayer as new CALayerMBS parentLayer.frame = r videoLayer.frame = r videoLayer.Hidden = false parentLayer.Hidden = false parentLayer.addSublayer(backgroundLayer) parentLayer.addSublayer(videoLayer) parentLayer.addSublayer(titleLayer) // 3. make animation dim tool as AVVideoCompositionCoreAnimationToolMBS = AVVideoCompositionCoreAnimationToolMBS.videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer(videoLayer, parentLayer) themeVideoComposition.animationTool = tool // Remove the file if it already exists (merger does not overwrite) OutputFile.Delete // export to output url dim PresetName as string = AVAssetExportSessionMBS.AVAssetExportPresetAppleM4V1080pHD exporter = new AVAssetExportSessionMBS(mergeComposition, PresetName) exporter.outputFile = OutputFile exporter.videoComposition = themeVideoComposition exporter.outputFileType = AVFoundation.AVFileTypeAppleM4V 'AVFileTypeQuickTimeMovie exporter.shouldOptimizeForNetworkUse = true exporter.exportAsynchronously End EventHandler
Property AVFoundation As MyAVFoundation
Property exporter As AVAssetExportSessionMBS
Property mergeComposition As AVMutableCompositionMBS
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 MyAVFoundation Inherits AVFoundationMBS
EventHandler Sub exportAsynchronouslyCompleted(ExportSession as AVAssetExportSessionMBS, tag as variant) dim e as NSErrorMBS = ExportSession.error if e <> nil then MsgBox e.LocalizedDescription+EndOfLine+e.LocalizedFailureReason+EndOfLine+e.LocalizedRecoverySuggestion else MsgBox "export done." end if End EventHandler
End Class
End Project

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


The biggest plugin in space...