Platforms to show: All Mac Windows Linux Cross-Platform

/AVFoundation/Transcode parallel


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

You find this example project in your Plugins Download as a Xojo project file within the examples folder: /AVFoundation/Transcode parallel

This example is the version from Fri, 23th May 2013.

Project "Transcode parallel.xojo_binary_project"
Class App Inherits Application
Const kEditClear = "&Löschen"
Const kFileQuit = "Beenden"
Const kFileQuitShortcut = ""
EventHandler Sub Open() if AVFoundation.available = false then MsgBox "Please run on Mac OS X 10.7 and newer." quit end if AVFoundation = new MyAVFoundation dim f as FolderItem = SpecialFolder.Desktop.Child("test.m4a") if f.Exists = false then MsgBox "This example needs a test.m4a file on your desktop." quit end if Run f, 1, ".m4a", AVFoundationMBS.AVFileTypeMPEG4, AVFoundationMBS.kAudioFormatMPEG4AAC Run f, 2, ".m4a", AVFoundationMBS.AVFileTypeMPEG4, AVFoundationMBS.kAudioFormatMPEG4AAC Run f, 1, ".wav", AVFoundationMBS.AVFileTypeWAVE, AVFoundationMBS.kAudioFormatLinearPCM Run f, 2, ".wav", AVFoundationMBS.AVFileTypeWAVE, AVFoundationMBS.kAudioFormatLinearPCM Run f, 1, " Apple Lossless.m4a", AVFoundationMBS.AVFileTypeAppleM4A, AVFoundationMBS.kAudioFormatAppleLossless Run f, 2, " Apple Lossless.m4a", AVFoundationMBS.AVFileTypeAppleM4A, AVFoundationMBS.kAudioFormatAppleLossless End EventHandler
Sub Log(s as string) LogWindow.list.addrow s End Sub
Sub MoveFileToTrash(f as FolderItem) dim r as FolderItem call MacFileOperationMBS.MoveObjectToTrashSync(f, r, MacFileOperationMBS.kFSFileOperationDefaultOptions) End Sub
Sub Run(file as folderitem, channels as integer, extension as string, OutputFileType as string, format as string) dim songAsset as AVURLAssetMBS = AVURLAssetMBS.URLAssetWithFile(file) dim assetError as NSErrorMBS dim assetReader as AVAssetReaderMBS = AVAssetReaderMBS.assetReaderWithAsset(songAsset, assetError) if assetError<>nil then dim e as string = assetError.localizedDescription log "Error: "+e break Return end if dim audioSettings as Dictionary = nil // no settings dim tracks() as AVAssetTrackMBS = songAsset.tracks dim assetReaderOutput as AVAssetReaderAudioMixOutputMBS = AVAssetReaderAudioMixOutputMBS.assetReaderAudioMixOutputWithAudioTracks(tracks, audioSettings) if not assetReader.canAddOutput(assetReaderOutput) then break log "can't add reader output... die!" return end if assetReader.addOutput(assetReaderOutput) dim exportFile as folderitem = SpecialFolder.Desktop.Child("test"+str(channels)+extension) if exportFile<>Nil then MoveFileToTrash exportFile exportFile = SpecialFolder.Desktop.Child("test"+str(channels)+extension) end if dim assetWriter as AVAssetWriterMBS = AVAssetWriterMBS.assetWriterWithFile(exportFile, outputFileType, assetError) if assetError<>nil then dim e as string = assetError.localizedDescription log "Error: "+e break Return end if dim channelLayout as new QTAudioChannelLayoutMBS if channels = 1 then channelLayout.ChannelLayoutTag = QTAudioChannelLayoutMBS.kAudioChannelLayoutTag_Mono elseif channels = 2 then channelLayout.ChannelLayoutTag = QTAudioChannelLayoutMBS.kAudioChannelLayoutTag_Stereo else break end if dim outputSettings as new Dictionary if format = AVFoundationMBS.kAudioFormatLinearPCM then // uncompressed needs extra values outputSettings.Value(AVFoundationMBS.AVLinearPCMBitDepthKey) = 16 outputSettings.Value(AVFoundationMBS.AVLinearPCMIsNonInterleaved) = false outputSettings.Value(AVFoundationMBS.AVLinearPCMIsFloatKey) = false outputSettings.Value(AVFoundationMBS.AVLinearPCMIsBigEndianKey) = false end if if format = AVFoundationMBS.kAudioFormatAppleLossless then outputSettings.Value(AVFoundationMBS.AVEncoderBitDepthHintKey) = 16 end if outputSettings.Value(AVFoundationMBS.AVFormatIDKey) = OSTypeFromStringMBS(format) outputSettings.Value(AVFoundationMBS.AVSampleRateKey) = 44100.0 outputSettings.Value(AVFoundationMBS.AVNumberOfChannelsKey) = channels outputSettings.Value(AVFoundationMBS.AVChannelLayoutKey) = channelLayout.Memory dim assetWriterInput as AVAssetWriterInputMBS = AVAssetWriterInputMBS.assetWriterInputWithMediaType(AVFoundationMBS.AVMediaTypeAudio, outputSettings) if assetWriter.canAddInput(assetWriterInput) then assetWriter.addInput(assetWriterInput) else break log "can't add asset writer input... die!" return end if assetWriterInput.expectsMediaDataInRealTime = false call assetWriter.startWriting assetReader.startReading dim soundTrack as AVAssetTrackMBS = tracks(0) dim startTime as CMTimeMBS = CMTimeMBS.Make(0, soundTrack.naturalTimeScale) assetWriter.startSessionAtSourceTime(startTime) // keep all the objects around in a global object for this job dim t as new TranscodeOperation t.assetReader = assetReader t.assetWriter = assetWriter t.assetWriterInput = assetWriterInput t.assetReaderOutput = assetReaderOutput t.exportFile = exportFile log "Starting conversion "+str(t.id)+"..." // here we pass ID for job so we can later find it back assetWriterInput.requestMediaDataWhenReadyOnQueue(assetWriterInput, AssetReaderOutput, t.id) End Sub
Property AVFoundation As MyAVFoundation
End Class
Class LogWindow Inherits Window
Control List Inherits Listbox
ControlInstance List Inherits Listbox
End Control
End Class
MenuBar MenuBar1
MenuItem FileMenu = "&Ablage"
MenuItem FileQuit = "#App.kFileQuit"
MenuItem EditMenu = "&Bearbeiten"
MenuItem EditUndo = "&Rückgängig"
MenuItem UntitledMenu1 = "-"
MenuItem EditCut = "&Ausschneiden"
MenuItem EditCopy = "&Kopieren"
MenuItem EditPaste = "&Einfügen"
MenuItem EditClear = "#App.kEditClear"
MenuItem UntitledMenu0 = "-"
MenuItem EditSelectAll = "&Alles auswählen"
End MenuBar
Class MyAVFoundation Inherits AVFoundationMBS
EventHandler Sub requestMediaDataWhenReadyOnQueueFinished(tag as integer) logwindow.List.AddRow "Finished "+str(tag) // we do all the stuff with IDs and operations for this. To find the object here! dim t as TranscodeOperation = TranscodeOperation.Operation(tag) t.close End EventHandler
End Class
Class TranscodeOperation
Sub Cleanup() if assetWriter<>nil then call assetWriter.finishWriting end if if assetReader<>nil then assetReader.cancelReading end if app.log "Done. File size is "+str(exportFile.Length)+" bytes." // release a lot of stuff assetReader = nil assetReaderOutput = nil assetWriter = nil assetWriterInput = nil Close End Sub
Sub Close() // remove from global list dim n as integer = Operations.IndexOf(self) if n>=0 then Operations.Remove n end if End Sub
Sub Constructor() // get a new ID static IDCounter as integer IDCounter = IDCounter + 1 ID = IDCounter Operations.Append self End Sub
Shared Function Operation(ID as integer) As TranscodeOperation for each o as TranscodeOperation in Operations if o.ID = ID then Return o end if next End Function
Property ID As integer
Property Private Shared Operations() As TranscodeOperation
Property assetReader As AVAssetReaderMBS
Property assetReaderOutput As AVAssetReaderOutputMBS
Property assetWriter As AVAssetWriterMBS
Property assetWriterInput As AVAssetWriterInputMBS
Property exportFile As FolderItem
End Class
End Project

See also:

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


The biggest plugin in space...