4

私のアプリケーションは、カスタム形式のビューアーであり、明確に定義された XML マニフェストとリソース (画像や動画など) を含む zip ファイルです。zlib を使用してメモリ内の zip ファイルを開き、リソースの表示に進みます。

私が遭遇した問題の 1 つは、どうやら QTMovie が MIME タイプを判別できないため、ビデオを適切に表示できないことです。ファイルからロードされたムービー ([QTMovie movieWithFile]) は完全に機能します。メモリからロードされた ([QTMovie movieWithData]) は動作を拒否します。

ファイル拡張子がないため、QTMovie は MIME タイプ情報を判別できないため、これは理にかなっています。少し検索した後、次の方法で QTDataReference を使用することにしました。

NSData *movieData = ...read from memory...;
QTDataReference *movieDataReference = [[QTDataReference alloc] initWithReferenceToData:movieData name:fileName MIMEType:@"video/x-m4v"];
QTMovie *mov = [QTMovie movieWithDataReference:movieDataReference error:&err];

これはうまく機能しますが、MIMEType のハードコーディングは理想とはほど遠いものです。ファイル名と拡張子にアクセスできるので、UTI を使用して MIME タイプを見つけようとしました (#macdev の親切な方々に感謝します)。

- (NSString*)mimeTypeForExtension:(NSString*)ext {

    CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,(CFStringRef)ext,NULL);
    return NSMakeCollectable(UTTypeCopyPreferredTagWithClass((CFStringRef)UTI,kUTTagClassMIMEType));
}

ただし、これは機能しません。明らかに、拡張機能と対応する MIME タイプの内部 OS X データベースがどこかにあります。そうしないと、ディスクからのムービーは機能しません。どうすればアクセスできますか?

ありがとう!

4

3 に答える 3

8

あなたが抱えている問題は、m4v と m4p が Launch Services に登録された MIME タイプを持っていないことです (おそらく m4v と m4p の MIME タイプが標準ではないため)。いずれにせよ、おそらくすべきことは、このようなエッジ ケースを処理し、関数が返されたときに nil をチェックすることです (拡張機能が登録されておらず、処理されていない場合)。

もう1つのことは、現在の使用でメモリをリークしていることです。ガベージ コレクションを使用していると思いますが、最初の呼び出しでは決して解放されない CFString が作成されます。メソッドの推奨される実装は次のとおりです。

-(NSString*)mimeTypeForExtension:(NSString*)ext
{
    NSAssert( ext, @"Extension cannot be nil" );
    NSString* mimeType = nil;

    CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,
        (CFStringRef)ext, NULL);
    if( !UTI ) return nil;

    CFStringRef registeredType = UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType);
    if( !registeredType ) // check for edge case
    {
        if( [ext isEqualToString:@"m4v"] )
            mimeType = @"video/x-m4v";
        else if( [ext isEqualToString:@"m4p"] )
            mimeType = @"audio/x-m4p";
        // handle anything else here that you know is not registered
    } else {
        mimeType = NSMakeCollectable(registeredType);
    }

    CFRelease(UTI);
    return mimeType;
}
于 2008-11-19T22:54:40.593 に答える
6

NSWorkspace を使用して、システムにファイルの UTI を推測させることができます。

-(NSString *)mimeTypeForFileAtPath:(NSString *)path error:(NSError **)err {
  NSString *uti, *mimeType = nil;

  if (!(uti = [[NSWorkspace sharedWorkspace] typeOfFile:path error:err]))
    return nil;
  if (err)
    *err = nil;

  if ((mimeType = (NSString *)UTTypeCopyPreferredTagWithClass((CFStringRef)uti, kUTTagClassMIMEType)))
    mimeType = NSMakeCollectable(mimeType);

  return mimeType;
}
于 2009-11-19T15:05:26.233 に答える
1

リターンを [mimeType autorelease] に変更することを提案します。- 私たちの中には、いまだに昔ながらの方法を使っている人もいます!

ありがとう!これは大きな助けになりました。

于 2009-07-18T20:34:19.890 に答える