Platforms to show: All Mac Windows Linux Cross-Platform
Required plugins for this example: MBS Main 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
This example is the version from Thu, 6th Apr 2016.
Project "Transcode.xojo_binary_project"
Class App Inherits Application
Const kEditClear = "&Löschen"
Const kFileQuit = "Beenden"
Const kFileQuitShortcut = ""
EventHandler Sub Open()
if AVAssetExportSessionMBS.available = false then
MsgBox "Please run on Mac OS X 10.7 or newer."
quit
end if
End EventHandler
End Class
Class Window1 Inherits Window
Control List Inherits Listbox
ControlInstance List Inherits Listbox
End Control
EventHandler Sub Open()
'Run 1, ".m4a", AVFoundationMBS.AVFileTypeMPEG4, false
'Run 2, ".m4a", AVFoundationMBS.AVFileTypeMPEG4, false
'Run 1, ".wav", AVFoundationMBS.AVFileTypeWAVE, true
Run 2, ".wav", AVFoundationMBS.AVFileTypeWAVE, true
End EventHandler
Sub Cleanup()
list.AddRow "Cleanup"
if assetWriter<>nil then
call assetWriter.finishWriting
end if
if assetReader<>nil then
assetReader.cancelReading
end if
MsgBox "Done. File size is "+str(exportFile.Length)+" bytes."
// release a lot of stuff
assetReader = nil
assetReaderOutput = nil
assetWriter = nil
assetWriterInput = nil
songAsset = nil
End Sub
Function FindFile(name as string) As FolderItem
// Look for file in parent folders from executable on
dim parent as FolderItem = app.ExecutableFile.Parent
while parent<>Nil
dim file as FolderItem = parent.Child(name)
if file<>Nil and file.Exists then
Return file
end if
parent = parent.Parent
wend
End Function
Sub Run(channels as integer, extension as string, OutputFileType as string, uncompressed as Boolean)
AVFoundation = new MyAVFoundation
dim file as FolderItem = FindFile("test.mov")
songAsset = AVURLAssetMBS.URLAssetWithFile(file)
list.AddRow "Loaded file: "+songAsset.URL
dim assetError as NSErrorMBS
assetReader = AVAssetReaderMBS.assetReaderWithAsset(songAsset, assetError)
if assetError<>nil then
dim e as string = assetError.localizedDescription
list.AddRow "Error: "+e
break
MsgBox e
Return
end if
dim audioSettings as Dictionary = nil // no settings
dim tracks() as AVAssetTrackMBS = songAsset.tracks
assetReaderOutput = AVAssetReaderAudioMixOutputMBS.assetReaderAudioMixOutputWithAudioTracks(tracks, audioSettings)
if not assetReader.canAddOutput(assetReaderOutput) then
break
MsgBox "can't add reader output... die!"
return
end if
assetReader.addOutput(assetReaderOutput)
exportFile = SpecialFolder.Desktop.Child("test"+str(channels)+extension)
assetWriter = AVAssetWriterMBS.assetWriterWithFile(exportFile, outputFileType, assetError)
if assetError<>nil then
dim e as string = assetError.localizedDescription
list.AddRow "Error: "+e
break
MsgBox e
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 uncompressed then
outputSettings.Value(AVFoundationMBS.AVFormatIDKey) = OSTypeFromStringMBS("lpcm") 'kAudioFormatLinearPCM
outputSettings.Value(AVFoundationMBS.AVLinearPCMBitDepthKey) = 16
outputSettings.Value(AVFoundationMBS.AVLinearPCMIsNonInterleaved) = false
outputSettings.Value(AVFoundationMBS.AVLinearPCMIsFloatKey) = false
outputSettings.Value(AVFoundationMBS.AVLinearPCMIsBigEndianKey) = false
else
outputSettings.Value(AVFoundationMBS.AVFormatIDKey) = OSTypeFromStringMBS("aac ") 'kAudioFormatMPEG4AAC
end if
outputSettings.Value(AVFoundationMBS.AVSampleRateKey) = 44100.0
outputSettings.Value(AVFoundationMBS.AVNumberOfChannelsKey) = channels
outputSettings.Value(AVFoundationMBS.AVChannelLayoutKey) = channelLayout.Memory
assetWriterInput = AVAssetWriterInputMBS.assetWriterInputWithMediaType(AVFoundationMBS.AVMediaTypeAudio, outputSettings)
if assetWriter.canAddInput(assetWriterInput) then
assetWriter.addInput(assetWriterInput)
else
break
MsgBox "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)
list.AddRow "Starting conversion..."
assetWriterInput.requestMediaDataWhenReadyOnQueue(assetWriterInput, AssetReaderOutput)
End Sub
Property AVFoundation As MyAVFoundation
Property assetReader As AVAssetReaderMBS
Property assetReaderOutput As AVAssetReaderOutputMBS
Property assetWriter As AVAssetWriterMBS
Property assetWriterInput As AVAssetWriterInputMBS
Property exportFile As FolderItem
Property songAsset As AVURLAssetMBS
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(assetWriterInput as AVAssetWriterInputMBS, assetReaderOutput as AVAssetReaderOutputMBS, tag as variant)
window1.List.AddRow "Finished"
window1.Cleanup
End EventHandler
EventHandler Sub requestMediaDataWhenReadyOnQueueProgress(assetWriterInput as AVAssetWriterInputMBS, assetReaderOutput as AVAssetReaderOutputMBS, convertedByteCount as Int64, LastBuffer as CMSampleBufferMBS, tag as variant)
window1.List.AddRow str(convertedByteCount)+" bytes done."
End EventHandler
End Class
End Project
See also:
The items on this page are in the following plugins: MBS AVFoundation Plugin.