Apple Developer Connection
高度な検索
Member Login ログイン | ご入会 ADC連絡先

Technical Note TN2120
QuickTime for Windows ActiveX/COMのよくある質問

QuickTime ActiveX/COMコントロールに関するよくある多くの質問に回答し、エクスポート、ムービーフレームのグラブ、イベント通知などのトピックについて説明します。





別の形式へのムービーのエクスポート

Q:ムービーを別の形式へエクスポートするには、どうすればよいのでしょうか。

A:ユーザがエクスポート操作に関するすべて(エクスポータタイプ、ファイル、オプションなど、QuickTime Playerのエクスポートと同様の設定)を設定できるようにしたい場合は、以下のコードを使用します。

リスト1:ユーザの設定によるエクスポート - 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)

  ' エクスポータのデータソース(トラックでも可)を設定する
  ex.SetDataSource Control.Movie

  ' エクスポートダイアログを表示する
  ex.ShowExportDialog

  Exit Sub

DoError:
  If Err.Number = &H8004FF80 Then
  ' MacOSエラー -128: ユーザが「キャンセル」ボタンをクリックしたので無視する
  Else
  MsgBox "ERROR:" + Hex(Err.Number)
  End If

  End Sub

リスト2:ユーザの設定によるエクスポート - C#

using AxQTOControlLib;

private void exportWithUserSettings(AxQTControl Control)
{

  // ユーザによる設定を使用してエクスポートを
  // 実行する。

  try
  {
    QTQuickTime qt = Control.QuickTime;

    if (qt.Exporters.Count == 0) qt.Exporters.Add();

    QTExporter ex = qt.Exporters[1];

    // エクスポータのデータソース(トラックでも可)を設定する
    ex.SetDataSource(Control.Movie);

    // エクスポートダイアログを表示する
    ex.ShowExportDialog();
  }
  catch(COMException ex)
  {
    // MacOSエラー -128: ユーザが「キャンセル」ボタンをクリックしたので無視する
    if (ex.ErrorCode != -2147156096 )
      MessageBox.Show("Error code:" + ex.ErrorCode.ToString("X"), "Export Error");
  }
  catch(Exception ex)
  {
    MessageBox.Show(ex.ToString(), "Export Error");
  }

}

先頭に戻る

エクスポートダイアログを表示しないでムービーを別の形式へエクスポート

Q:エクスポートダイアログを表示しないでムービーを別の形式へエクスポートするには、どうすればよいのでしょうか。

A:まず、QTExporterオブジェクトのインスタンスを作成し、次にそのデータソース(ムービーまたはトラック)、エクスポータタイプ(QuickTime Movie、AVI、3G、MPEG-4、PNGなど)、およびエクスポート先となるファイルを設定する必要があります。その後で、BeginExportを呼び出します。

次のように表示されます。

リスト3:エクスポートダイアログを表示しないでエクスポート - 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)

  ' エクスポータタイプを設定する:AVI、3G、MPEG-4、PNGなど
  ex.TypeName = "QuickTime Movie"

  ' エクスポートする選択範囲を設定する(オプション)
  ex.StartTime = 0      ' オプション
  ex.EndTime = Control.Movie.Duration      ' オプション

  ' エクスポータのデータソース(トラックでも可)を設定する
  ex.SetDataSource Control.Movie

  ' エクスポート先となるファイルの名前とパスを設定する
  ex.DestinationFileName = "D:\Movies\Exported\exportMovie.mov"

  ' エクスポートを実行する
  ex.BeginExport

  Exit Sub

DoError:
  If Err.Number = &H8004FF80 Then
  ' MacOSエラー -128: ユーザが「キャンセル」ボタンをクリックしたので無視する
  Else
  MsgBox "ERROR:" + Hex(Err.Number)
  End If

End Sub

リスト4:エクスポートダイアログを表示しないでエクスポート - 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];

    // エクスポータタイプを設定する:AVI、3G、MPEG-4、PNGなど
    ex.TypeName = "QuickTime Movie";

    // エクスポートする選択範囲を設定する(オプション)
    ex.StartTime = 0;      // オプション
    ex.EndTime = Control.Movie.Duration;      // オプション

    // エクスポータのデータソース(トラックでも可)を設定する
    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エラー -128: ユーザが「キャンセル」ボタンをクリックしたので無視する
    if (ex.ErrorCode != -2147156096 )
      MessageBox.Show("Error code:" + ex.ErrorCode.ToString("X"), "Export Error");
  }
  catch(Exception ex)
  {
    MessageBox.Show(ex.ToString(), "Export Error");
  }

}

先頭に戻る

バッチエクスポート操作の実行

Q:同じエクスポート設定を何度も再利用する「バッチ」エクスポート操作を実行するには、どうすればよいのでしょうか(似たようなことがC関数のMovieExportSetSettingsFromAtomContainerを使って実行できます)。

A:前述のように、まずQTExporterオブジェクトのインスタンスを作成し、次にそのデータソース、エクスポータタイプ、およびエクスポート先となるファイルを設定する必要があります。次に、選択したエクスポータタイプに対応したエクスポートオプションダイアログを表示するShowSettingsDialogを呼び出し、さらにBeginExportを呼び出します。エクスポータを設定したら、そのデータソースを変更して、他のムービーおよび/またはトラックを対象に何度でも再利用できます。

また、XMLプロパティ(文字列)として取得・設定することで、エクスポータ設定を永続化することもできます。

役に立つサンプルをいくつか以下に示します。

リスト5:バッチエクスポート操作 - VB 6

' 特定ディレクトリの有無を確認する
Function DirExists(path As String) As Boolean
    On Error Resume Next
    DirExists = (Dir$(path & "\nul") <> "")
End Function

' 特定ファイルの有無を確認する
Function FileExists(filename As String) As Boolean
    On Error Resume Next
    FileExists = (Dir$(filename) <> "")
End Function

' 文字列をテキストファイルに書き出す
Sub WriteTextFileContents(Text As String, filename As String, _
    Optional AppendMode As Boolean)
    Dim fnum As Integer, isOpen As Boolean
    On Error GoTo Error_Handler
    ' 次の空きファイル番号を取得する。
    fnum = FreeFile()
    If AppendMode Then
         Open filename For Append As #fnum
     Else
         Open filename For Output As #fnum
     End If
     ' 実行フローがここまで来れば、ファイルが正しく開かれている。
     isOpen = True
     ' 単一操作でファイルに出力する。
     Print #fnum, Text
     ' 意図的にエラーハンドラに進むことで、ファイルを閉じる。
Error_Handler:
     ' (もしあれば)エラーを発行する。ただし、先にファイルを閉じる。
     If isOpen Then Close #fnum
     If Err Then Err.Raise Err.Number, , Err.Description
End Sub

' テキストファイルの内容を文字列として読み取る
Function ReadTextFileContents(filename As String) As String
     Dim fnum As Integer, isOpen As Boolean
     On Error GoTo Error_Handler
     ' 次の空きファイル番号を取得する。
     fnum = FreeFile()
     Open filename For Input As #fnum
     ' 実行フローがここまで来れば、ファイルがエラーなしに開かれている。
     isOpen = True
     ' 単一操作で内容全体を読み取る。
     ReadTextFileContents = Input(LOF(fnum), fnum)
     ' 意図的にエラーハンドラに進むことで、ファイルを閉じる。
Error_Handler:
     ' (もしあれば)エラーを発行する。ただし、先にファイルを閉じる。
     If isOpen Then Close #fnum
     If Err Then Err.Raise Err.Number, , Err.Description
End Function

' カスタム設定でエクスポート操作を実行する。
' また、これらのエクスポート設定をファイルに保存する。
' 保存した設定は後で取り出して、ほかのエクスポートに
' 使用できる
Private Sub exportWithCustomSettings(Control As QTControl)

    ' カスタム設定を使用してエクスポートを
    ' 実行する。

    ' カスタム設定でエクスポート操作を
    ' 実行するには、まずQTExporterオブジェクトの
    ' インスタンスを作成し、次にそのデータソース
    ' (ムービーまたはトラック)、エクスポータタイプ
    ' (QuickTime Movie、AVI、3G、MPEG-4、PNGなど)、
    ' さらにエクスポート先となるファイルを
    ' 設定する必要がある。

    ' 次に、選択したエクスポータタイプに対応するエクスポートオプション
    ' ダイアログを表示するShowSettingsDialogを呼び出し、
    ' 最後にBeginExportを呼び出す。

    ' エクスポータを設定したら、
    ' そのデータソースを変更して、他のムービーや
    ' トラックで何度でも再利用できる。
    ' また、XMLプロパティ(文字列)を取得・設定することで、
    ' エクスポータ設定を永続化できる。

    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)

    ' エクスポータタイプを設定する:AVI、3G、MPEG-4、PNGなど
    ex.TypeName = "QuickTime Movie"

    ' エクスポートする選択範囲を設定する(オプション)
    ex.StartTime = 0      ' オプション
    ex.EndTime = Control.Movie.Duration      ' オプション

    ' エクスポータのデータソース(トラックでも可)を設定する
    ex.SetDataSource Control.Movie

    Dim exportFilePath As String
    exportFilePath = "C:\Movies\Exported.mov"

    ' エクスポート先となるファイルの名前とパスを設定する
    'ex.DestinationFileName = "C:\Movies\Exported.mov"
    ex.DestinationFileName = exportFilePath

    ' 選択したエクスポータタイプに対応する設定ダイアログを表示する
    ex.ShowSettingsDialog

    ' ここでエクスポートを実際に実行する
    ex.BeginExport

    Dim exportSettingsPath As String
    exportSettingsPath = App.path + "\\Settings"

    Dim exportSettingsFileName As String
    exportSettingsFileName = exportSettingsPath + "\\" + ex.TypeName + ".plist"

    ' エクスポータ設定を保存する
    If DirExists(exportSettingsPath) = False Then
        MkDir exportSettingsPath
    End If
    WriteTextFileContents ex.Settings.XML, exportSettingsFileName, False


    Exit Sub

ErrorHandler:
    If Err.Number = &H8004FF80 Then
        ' MacOSエラー -128: ユーザが「キャンセル」ボタンをクリックしたので無視する
    Else
        Beep
        Dim errStr As String
        errStr = "Failed with error #" & Hex(Err.Number) & ", " & Err.Description
        MsgBox errStr, vbCritical
    End If

End Sub

' 保存したエクスポート設定(ファイル)を使用してエクスポート操作を実行する
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)

    ' エクスポータタイプを設定する:AVI、3G、MPEG-4、PNGなど
    ex.TypeName = "QuickTime Movie"

    ' エクスポータのデータソース(トラックでも可)を設定する
    ex.SetDataSource Control.Movie

    ' 可能ならば、以前のエクスポータ設定をロードする
    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

    ' ムービーをエクスポートする
    ex.DestinationFileName = "C:\Movies\Exported2.mov"
    ex.ShowProgressDialog = True
    ex.BeginExport

End Sub

リスト6:バッチエクスポート操作 - 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";

    //エクスポータを設定する
    ex.ShowSettingsDialog();

    //ムービーをエクスポートする
    ex.DestinationFileName = "C:\Movies\Exported.mov";
    ex.ShowProgressDialog = true;
    ex.BeginExport();

    //エクスポータ設定を保存する
    if (!Directory.Exists(exporterSettingsPath))
        Directory.CreateDirectory(exporterSettingsPath);
    StreamWriter sw = File.CreateText(exporterSettingsFileName);
    sw.Write(ex.Settings.XML);
    sw.Close();


    次回、設定ファイルからこの設定を再ロードし、再利用できる。

    .
    .
    .
    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";

    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();

    //ムービーをエクスポートする
    ex.DestinationFileName = "C:\Movies\Exported.mov";
    ex.ShowProgressDialog = true;
    ex.BeginExport();

先頭に戻る

エクスポート設定ダイアログによるマシンのハング

Q:VB 6アプリケーションからShowSettingDialogを呼び出すと、エクスポート設定ダイアログが表示されたときにハングするようです。エクスポートオプションの値の調整やその他のことが何もできません。制御を取り戻すには、アプリケーションを強制終了する必要があります。私は何か間違えているのでしょうか。

A:VB 6アプリケーションをコンパイルして、VB 6開発環境の*外部で*実行ファイルを実行する場合、これは問題になりません(開発環境の外部で実行するアプリケーションをビルドするには、「ファイル」->「"MyApp.exe" の作成」を使用します)。ダイアログがロックしてしまう問題は、VB 6の「実行モード」でのみ発生します。

先頭に戻る

ムービーからの単一画像フレームの取得

Q:ムービーから単一フレームの画像を取得する方法はありますか?

A:1つの方法は、QTMoviecopyFrame(VARIANT Time)メソッドを使用して、指定ムービー時間の指定フレームのグラブをクリップボードに置くという方法です。その後は、Clipboardクラスメソッド(またはWin32クリップボード関数)を使って、画像を有用な形式で簡単に取得できます。

たとえば、次のようにします。

リスト7:ムービーフレームの画像を取得 - VB 6

Private Sub copyFrame(Control As QTControl)

    If Control.movie Is Nothing Then Exit Sub

    Dim movie As QTMovie
    Set movie = Control.movie

    ' ムービーの途中にあるフレームをグラブする
    movie.copyFrame ((movie.EndTime - movie.StartTime) / 2)

    If Clipboard.GetFormat(vbCFBitmap) Then
        '   ムービーフレームを描画する、など。
    End If

End Sub

リスト8:ムービーフレームの画像を取得 - C#

using AxQTOControlLib;

private void myCopyFrame(AxQTControl Control)
{
    if (Control.Movie == null) return;

    QTMovie theMovie = Control.Movie;

    // ムービーの途中にあるフレームをグラブする
    theMovie.CopyFrame((theMovie.EndTime - theMovie.StartTime) / 2);

    // フレームがクリップボードに置かれたので、データを取得する
    IDataObject data = Clipboard.GetDataObject();
    if (data != null)
    {
        // データを使って何かを実行する
    }
}

先頭に戻る

イベント通知受け取り登録

Q:QTEvent通知を受け取れるように登録するには、どうしたらよいのでしょうか。たとえば、「Buffering...」などのストリーミングステータスメッセージを受け取りたいと思っています。

A:いくつかのQuickTimeオブジェクト、通常はQTMovieQTTrack、およびQTQuickTimeオブジェクトに関するQTEvent通知の受け取りを登録できます。「Buffering...」タイプのステータス文字列通知を受け取るには、ムービーインスタンスをロードした後に、そのインスタンスに関するqtEventShowStatusStringRequest通知の受け取りを登録します。

その方法を以下に示します。

リスト9:QTEventステータス文字列通知の受け取りの登録 - VB 6

' ステータス文字列リスナー
QTControl1.Movie.EventListeners.Add _
  QTOLibrary.QTEventClassesEnum.qtEventClassApplicationRequest, _
  QTOLibrary.QTEventIDsEnum.qtEventShowStatusStringRequest

リスト10:QTEventステータス文字列通知の受け取りの登録 - C#

// ステータス文字列リスナー
axQTControl1.Movie.EventListeners.Add(
  QTEventClassesEnum.qtEventClassApplicationRequest,
  QTEventIDsEnum.qtEventShowStatusStringRequest, 0, null);

後は、QTEventハンドラで、この通知IDを探すだけです。

リスト11:ステータス文字列通知に対するQTEventハンドラ関数 - 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)

' さまざまなQuickTimeイベントを処理するコード

Select Case EventID

  ' ステータス文字列
  Case QTEventIDsEnum.qtEventShowStatusStringRequest
    Dim msg As String
    msg = EventObject.GetParam _
    (QTEventObjectParametersEnum.qtEventParamStatusString).ToString()
    Debug.Print "qtEventShowStatusStringRequest :" & msg

End Select

End Sub

リスト12:ステータス文字列通知に対するQTEventハンドラ関数 - 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;
   }
}

その他にも便利な通知がいくつかあります。

// QTEventClassesEnum, QTEventIDsEnum

qtEventClassStateChange, qtEventRateWillChange
qtEventClassStateChange, qtEventMovieDidEnd
qtEventClassTemporal, qtEventTimeWillChange
qtEventClassProgress, qtEventExportProgress
qtEventClassAudio, qtEventAudioVolumeDidChange

先頭に戻る

ムービー注釈の取得

Q:GetUserDataメソッドを使用してムービー注釈データ(ムービーのタイトル、作成者など)を取得したいと思っています。しかし、このメソッドにユーザデータ識別子(qtAnnotationFullNameqtAnnotationAuthorなど)の1つを渡すと、いつも戻り値として空の文字列を受け取ります。何が間違っているのでしょうか。

A:存在しない注釈を要求すると、QTMovieオブジェクトによって例外が生成されます。

注:存在しない注釈については、空の注釈と区別できるように例外がスローされます。

次のように、QuickTime ControlのErrorHandlingプロパティを明示的に設定することで、COM例外を生成するようにできます。

AxQTControl1.ErrorHandling = QTErrorHandlingOptionsEnum.qtErrorHandlingRaiseException

存在しない注釈を要求したときは、例外をキャッチしながらも無視するようにします。たとえば、その方法を示す、VB 6で書かれた簡単な関数を以下に示します。

リスト13:ムービー注釈を取得する際の例外のキャッチ - 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

これで、前記の関数を次のように呼び出すことで、ムービーのメタデータを簡単に取得できます。

リスト14:ムービーメタデータの取得 - VB 6

Dim fullName As String
fullName = ""
fullName = fullName + "Full Name:" + GetMovieAnnotation(QTControl1.Movie, _
    QTAnnotationsEnum.qtAnnotationFullName)
fullName = fullName + vbCrLf

同じようなことをするC#を以下に示します。

リスト15:ムービーメタデータの取得 - C#


// ムービー注釈データを取得し、エラーをすべてキャッチする
private string Get_MovieAnnotation(int inAnnoID, QTMovie inMovie)
{
    string annoStr = string.Empty;
    if (inMovie != null)
    {
        try
        {
            // ムービー注釈を取得する
            annoStr = inMovie.get_Annotation(inAnnoID);
        }
        catch
        {
            // ここでエラーがあれば、要求した注釈がムービーに
            // 含まれていないことを示す
        }
    }
    return annoStr;
}

.
.
.
// ムービーのメタデータを取得する
    string fullName = string.Empty;
    QTMovie theMovie = axQTControl1.Movie;

    fullName = fullName + @"Full Name:" +
        Get_MovieAnnotation((int)QTAnnotationsEnum.qtAnnotationFullName, theMovie);

先頭に戻る

その他の参考資料

先頭に戻る

ドキュメント改訂履歴

日付メモ
2006-05-02初版

掲載日: 2006-05-02




Did this document help you?
Yes: Tell us what works for you.

It’s good, but: Report typos, inaccuracies, and so forth.

It wasn’t helpful: Tell us what would have helped.