|
Exporting a movie to another formatQ: How do I export a movie to another format? A: If you want to allow the user to configure everything for the export operation (exporter type, file, options: same as QuickTime Player export) then use the following: Listing 1: User configured export - VB 6 Private Sub exportWithUserSettings(Control As QTControl) Dim qt As QTQuickTime Dim ex As QTExporter On Error GoTo DoError Set qt = Control.QuickTime If qt.Exporters.count = 0 Then qt.Exporters.Add Set ex = qt.Exporters(1) 'Set exporter data source - could also be a track ex.SetDataSource Control.Movie 'Display the export dialog ex.ShowExportDialog Exit Sub DoError: If Err.Number = &H8004FF80 Then ' MacOS error -128: user clicked "cancel" button so ignore Else MsgBox "ERROR: " + Hex(Err.Number) End If End Sub Listing 2: User configured export - C# using AxQTOControlLib; private void exportWithUserSettings(AxQTControl Control) { // Perform export with user configured // settings. try { QTQuickTime qt = Control.QuickTime; if (qt.Exporters.Count == 0) qt.Exporters.Add(); QTExporter ex = qt.Exporters[1]; // Set exporter data source - could also be a track ex.SetDataSource(Control.Movie); // Display the export dialog ex.ShowExportDialog(); } catch(COMException ex) { // MacOS error -128: user clicked "cancel" button so ignore if (ex.ErrorCode != -2147156096 ) MessageBox.Show("Error code: " + ex.ErrorCode.ToString("X"), "Export Error"); } catch(Exception ex) { MessageBox.Show(ex.ToString(), "Export Error"); } } Exporting a movie to another format without displaying the export dialogQ: How do I export a movie to another format without displaying the export dialog? A: You first need to create an instance of the Here's how it looks: Listing 3: Exporting without displaying the export dialog - VB 6 Private Sub exportWithoutDialog(Control As QTControl) Dim qt As QTQuickTime Dim ex As QTExporter On Error GoTo DoError Set qt = Control.QuickTime If qt.Exporters.count = 0 Then qt.Exporters.Add Set ex = qt.Exporters(1) 'Set exporter type: AVI, 3G, MPEG-4, PNG, etc. ex.TypeName = "QuickTime Movie" 'Set selection to export (optional) ex.StartTime = 0 'Optional ex.EndTime = Control.Movie.Duration 'Optional 'Set exporter data source - could also be a track ex.SetDataSource Control.Movie 'Set name and path for exported file ex.DestinationFileName = "D:\Movies\Exported\exportMovie.mov" 'Do the export ex.BeginExport Exit Sub DoError: If Err.Number = &H8004FF80 Then ' MacOS error -128: user clicked "cancel" button so ignore Else MsgBox "ERROR: " + Hex(Err.Number) End If End Sub Listing 4: Exporting without displaying the export dialog - C# using AxQTOControlLib; private void exportWithoutDialog(AxQTControl Control) { try { QTQuickTime qt = Control.QuickTime; if (qt.Exporters.Count == 0) qt.Exporters.Add(); QTExporter ex = qt.Exporters[1]; // Set exporter type: AVI, 3G, MPEG-4, PNG, etc. ex.TypeName = "QuickTime Movie"; // Set selection to export (optional) ex.StartTime = 0; // Optional ex.EndTime = Control.Movie.Duration; // Optional // Set exporter data source - could also be a track ex.SetDataSource(Control.Movie); ex.DestinationFileName = @"C:\Movies\exported.mov"; ex.ShowProgressDialog = true; Cursor.Current = Cursors.WaitCursor; ex.BeginExport(); Cursor.Current = Cursors.Arrow; } catch(COMException ex) { // MacOS error -128: user clicked "cancel" button so ignore if (ex.ErrorCode != -2147156096 ) MessageBox.Show("Error code: " + ex.ErrorCode.ToString("X"), "Export Error"); } catch(Exception ex) { MessageBox.Show(ex.ToString(), "Export Error"); } } Performing a batch export operationQ: How do I perform a "batch" export operation, re-using the same export settings over and over again (similar to what can be done using the A: As described previously, you first need to create an instance of the You can also persist exporter settings by getting and setting the XML property (a string). Here are some samples that should help. Listing 5: Batch export operation - VB 6 ' Test for the existence of a specific directory Function DirExists(path As String) As Boolean On Error Resume Next DirExists = (Dir$(path & "\nul") <> "") End Function ' Test for the existence of a specific file Function FileExists(filename As String) As Boolean On Error Resume Next FileExists = (Dir$(filename) <> "") End Function ' Write out a string to a text file Sub WriteTextFileContents(Text As String, filename As String, _ Optional AppendMode As Boolean) Dim fnum As Integer, isOpen As Boolean On Error GoTo Error_Handler ' Get the next free file number. fnum = FreeFile() If AppendMode Then Open filename For Append As #fnum Else Open filename For Output As #fnum End If ' If execution flow gets here, the file has been opened correctly. isOpen = True ' Print to the file in one single operation. Print #fnum, Text ' Intentionally flow into the error handler to close the file. Error_Handler: ' Raise the error (if any), but first close the file. If isOpen Then Close #fnum If Err Then Err.Raise Err.Number, , Err.Description End Sub ' Read text file contents as a string Function ReadTextFileContents(filename As String) As String Dim fnum As Integer, isOpen As Boolean On Error GoTo Error_Handler ' Get the next free file number. fnum = FreeFile() Open filename For Input As #fnum ' If execution flow got here, the file has been open without error. isOpen = True ' Read the entire contents in one single operation. ReadTextFileContents = Input(LOF(fnum), fnum) ' Intentionally flow into the error handler to close the file. Error_Handler: ' Raise the error (if any), but first close the file. If isOpen Then Close #fnum If Err Then Err.Raise Err.Number, , Err.Description End Function ' Perform an export operation with custom settings ' Also saves these export settings to a file which ' can be later be retrieved and used for additional ' exports Private Sub exportWithCustomSettings(Control As QTControl) 'Perform export with custom configured 'settings. 'To perform an export operation with custom 'configured Settings you first need to create 'an instance of the QTExporter object and then 'you need to configure it by setting its data 'source (movie or track) and exporter type '(QuickTime Movie, AVI, 3G, MPEG-4, PNG, etc.) 'as well as the file you want to export to. 'Then call ShowSettingsDialog to display the 'export options dialog for the selected exporter 'type, and finally call BeginExport. 'Once you have configured an exporter, you can 'change its data source and reuse it with other 'movies and/or tracks as many times as you like. 'You can also persist exporter settings by getting 'and setting the XML property (a string). On Error GoTo ErrorHandler If Control.Movie Is Nothing Then Exit Sub Dim qt As QTQuickTime Dim ex As QTExporter Set qt = Control.QuickTime If qt.Exporters.Count = 0 Then qt.Exporters.Add End If Set ex = qt.Exporters(1) 'Set exporter type: AVI, 3G, MPEG-4, PNG, etc. ex.TypeName = "QuickTime Movie" 'Set selection to export (optional) ex.StartTime = 0 'Optional ex.EndTime = Control.Movie.Duration 'Optional 'Set exporter data source - could also be a track ex.SetDataSource Control.Movie Dim exportFilePath As String exportFilePath = "C:\Movies\Exported.mov" 'Set name and path for exported file 'ex.DestinationFileName = "C:\Movies\Exported.mov" ex.DestinationFileName = exportFilePath 'Display the settings dialog for the selected exporter type ex.ShowSettingsDialog 'Now do the actual export ex.BeginExport Dim exportSettingsPath As String exportSettingsPath = App.path + "\\Settings" Dim exportSettingsFileName As String exportSettingsFileName = exportSettingsPath + "\\" + ex.TypeName + ".plist" 'Save Exporter Settings If DirExists(exportSettingsPath) = False Then MkDir exportSettingsPath End If WriteTextFileContents ex.Settings.XML, exportSettingsFileName, False Exit Sub ErrorHandler: If Err.Number = &H8004FF80 Then ' MacOS error -128: user clicked "cancel" button so ignore Else Beep Dim errStr As String errStr = "Failed with error #" & Hex(Err.Number) & ", " & Err.Description MsgBox errStr, vbCritical End If End Sub ' Perform export opertation using saved export settings (file) Private Sub exportAgainWithSavedSettings(Control As QTControl) If Control.Movie Is Nothing Then Exit Sub Dim qt As QTQuickTime Dim ex As QTExporter Set qt = Control.QuickTime If qt.Exporters.Count = 0 Then qt.Exporters.Add End If Set ex = qt.Exporters(1) 'Set exporter type: AVI, 3G, MPEG-4, PNG, etc. ex.TypeName = "QuickTime Movie" 'Set exporter data source - could also be a track ex.SetDataSource Control.Movie 'Load previous exporter settings if possible Dim exportSettingsPath As String exportSettingsPath = App.path + "\\Settings" Dim exportSettingsFileName As String exportSettingsFileName = exportSettingsPath + "\\" + ex.TypeName + ".plist" If (FileExists(exportSettingsFileName) = True) Then Dim cf As New CFObject cf.XML = ReadTextFileContents(exportSettingsFileName) ex.Settings = cf Else ex.ShowSettingsDialog End If 'Export Movie ex.DestinationFileName = "C:\Movies\Exported2.mov" ex.ShowProgressDialog = True ex.BeginExport End Sub Listing 6: Batch export operation - C# QTQuickTime qt = axQTControl1.QuickTime; if (qt.Exporters.Count == 0) qt.Exporters.Add(); QTExporter ex = qt.Exporters[1]; ex.TypeName = "3G"; ex.SetDataSource(axQTControl1.Movie); String exporterSettingsPath = Application.StartupPath + "\\Settings"; String exporterSettingsFileName = exporterSettingsPath + "\\" + ex.TypeName + ".plist"; //Configure Exporter ex.ShowSettingsDialog(); //Export movie ex.DestinationFileName = "C:\Movies\Exported.mov"; ex.ShowProgressDialog = true; ex.BeginExport(); //Save exporter settings if (!Directory.Exists(exporterSettingsPath)) Directory.CreateDirectory(exporterSettingsPath); StreamWriter sw = File.CreateText(exporterSettingsFileName); sw.Write(ex.Settings.XML); sw.Close(); Next time you can reload these settings from the settings file and reuse them again: . . . QTQuickTime qt = axQTControl1.QuickTime; if (qt.Exporters.Count == 0) qt.Exporters.Add(); QTExporter ex = qt.Exporters[1]; ex.TypeName = "3G"; ex.SetDataSource(axQTControl1.Movie); // Load previous exporter settings if available String exporterSettingsPath = Application.StartupPath + "\\Settings"; String exporterSettingsFileName = exporterSettingsPath + "\\" + ex.TypeName + ".plist"; if (File.Exists(exporterSettingsFileName)) { StreamReader sr = new StreamReader(exporterSettingsFileName); CFObject cf = new CFObject(); cf.XML = sr.ReadToEnd(); ex.Settings = cf; sr.Close(); } else ex.ShowSettingsDialog(); //Export movie ex.DestinationFileName = "C:\Movies\Exported.mov"; ex.ShowProgressDialog = true; ex.BeginExport(); Export settings dialog hangs my machine?Q: When I call the A: If you compile the VB 6 application and run the executable *outside* of the VB 6 development environment this will not be a problem (use File->Make "MyApp.exe" to build the application for execution outside the development environment). This locked dialog issue only occurs in VB 6 "Run Mode". Getting single image frames from a movieQ: Is there a way to get an image of a single frame from a movie? A: One way is to use the Something like this: Listing 7: Getting an image for a movie frame - VB 6 Private Sub copyFrame(Control As QTControl) If Control.movie Is Nothing Then Exit Sub Dim movie As QTMovie Set movie = Control.movie ' grab a frame in the middle of the movie movie.copyFrame ((movie.EndTime - movie.StartTime) / 2) If Clipboard.GetFormat(vbCFBitmap) Then ' Draw movie frame, etc. End If End Sub Listing 8: Getting an image for a movie frame - C# using AxQTOControlLib; private void myCopyFrame(AxQTControl Control) { if (Control.Movie == null) return; QTMovie theMovie = Control.Movie; // grab frame from middle of movie theMovie.CopyFrame((theMovie.EndTime - theMovie.StartTime) / 2); // frame is now on the clipboard so let's get the data IDataObject data = Clipboard.GetDataObject(); if (data != null) { // do what you want with data... } } Register for event notificationsQ: How do I register for A: You can register for Here's how: Listing 9: Registering for QTEvent Status String Notifications - VB 6 'status string listener QTControl1.Movie.EventListeners.Add _ QTOLibrary.QTEventClassesEnum.qtEventClassApplicationRequest, _ QTOLibrary.QTEventIDsEnum.qtEventShowStatusStringRequest Listing 10: Registering for QTEvent Status String Notifications - C# // status string listener axQTControl1.Movie.EventListeners.Add( QTEventClassesEnum.qtEventClassApplicationRequest, QTEventIDsEnum.qtEventShowStatusStringRequest, 0, null); Then, in your Listing 11: A QTEvent handler function for status string notifications - VB 6 Private Sub QTControl1_QTEvent(ByVal EventClass As Long, ByVal EventID As Long,_ ByVal Phase As Long, ByVal EventObject As QTOLibrary.IQTEventObject, _ Cancel As Boolean) 'Code to handle various QuickTime Events Select Case EventID 'status strings Case QTEventIDsEnum.qtEventShowStatusStringRequest Dim msg As String msg = EventObject.GetParam _ (QTEventObjectParametersEnum.qtEventParamStatusString).ToString() Debug.Print "qtEventShowStatusStringRequest : " & msg End Select End Sub Listing 12: A QTEvent handler function for status string notifications - C# private void axQTControl1_QTEvent(object sender, AxQTOControlLib._IQTControlEvents_QTEventEvent e) { switch (e.eventID) { case (int) QTEventIDsEnum.qtEventShowStatusStringRequest: string msg = e.eventObject.GetParam( QTEventObjectParametersEnum.qtEventParamStatusString).ToString(); Console.WriteLine("qtEventShowStatusStringRequest : {0}", msg); break; } } Some other useful notifications include: // QTEventClassesEnum, QTEventIDsEnum qtEventClassStateChange, qtEventRateWillChange qtEventClassStateChange, qtEventMovieDidEnd qtEventClassTemporal, qtEventTimeWillChange qtEventClassProgress, qtEventExportProgress qtEventClassAudio, qtEventAudioVolumeDidChange Getting movie annotationsQ: I'd like to get movie annotation data (movie title, author, and so on) with the A: If you ask for an annotation that doesn't exist the Note: An exception is thrown for annotations which do not exist so they may be differentiated from empty annotations. You can explicitly configure the AxQTControl1.ErrorHandling = QTErrorHandlingOptionsEnum.qtErrorHandlingRaiseException When you ask for an annotation that doesn't exist you'll want to catch but ignore the exception. For example, here's a simple function written in VB 6 showing how to do this: Listing 13: Catching exceptions when getting movie annotations - VB 6. Function GetMovieAnnotation(ByRef mov As QTMovie, ByVal annotationID As Long) _ As String On Error Resume Next Dim valStr As String valStr = "" valStr = mov.Annotation(annotationID) GetMovieAnnotation = valStr End Function Now you can easily get movie metadata by calling this function as shown here: Listing 14: Getting movie metadata - VB 6 Dim fullName As String fullName = "" fullName = fullName + "Full Name: " + GetMovieAnnotation(QTControl1.Movie, _ QTAnnotationsEnum.qtAnnotationFullName) fullName = fullName + vbCrLf Here's C# code which does a similar thing: Listing 15: Getting movie metadata - C# // Get movie annotation data and catch any errors private string Get_MovieAnnotation(int inAnnoID, QTMovie inMovie) { string annoStr = string.Empty; if (inMovie != null) { try { // get movie annotation annoStr = inMovie.get_Annotation(inAnnoID); } catch { // an error here means movie does not contain // the desired annotation } } return annoStr; } . . . // Get Movie MetaData string fullName = string.Empty; QTMovie theMovie = axQTControl1.Movie; fullName = fullName + @"Full Name: " + Get_MovieAnnotation((int)QTAnnotationsEnum.qtAnnotationFullName, theMovie); Other ReferencesDocument Revision History
Posted: 2006-05-02 |
|