Question

Mon application est une visionneuse pour un format personnalisé, un fichier zip avec un manifeste XML bien défini et des ressources, telles que des images et des films. J'utilise zlib pour ouvrir le fichier zip en mémoire, puis affiche lesdites ressources.

Un problème que j'ai rencontré est que je ne parviens pas à afficher correctement les vidéos, apparemment parce que QTMovie ne peut pas déterminer le type MIME. La vidéo chargée à partir d'un fichier ([QTMovie movieWithFile]) fonctionne parfaitement. Chargé de la mémoire ([QTMovie movieWithData]) refuse de fonctionner.

Cela a du sens, faute d’extension de fichier, QTMovie ne peut pas déterminer les informations de type mime. Après quelques recherches, j'ai eu recours à QTDataReference de la manière suivante:

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

Cela fonctionne bien, mais le codage en dur de MIMEType est loin d’être idéal. J'ai accès au nom de fichier et à l'extension. J'ai donc essayé de trouver le type mime en utilisant UTI (grâce aux gentils gens de #macdev):

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

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

Cela ne fonctionne cependant pas. Clairement, il existe une base de données interne OS X d'extensions et de types mime correspondants, quelque part. Sinon, les films à partir du disque ne fonctionneraient pas. Comment puis-je y accéder?

Merci!

Était-ce utile?

La solution

Le problème que vous rencontrez est que m4v et m4p n’ont pas de types mime enregistrés auprès de Launch Services (probablement parce que le type mime pour m4v et m4p n’est pas standard). Quoi qu'il en soit, vous devriez probablement gérer les cas extrêmes de ce type, puis rechercher la valeur nil au retour de la fonction (si l'extension est à la fois non enregistrée et non gérée par vous).

L'autre chose est que vous perdez de la mémoire avec votre utilisation actuelle. Je suppose que vous utilisez la récupération de place, mais le premier appel crée un CFString qui n'est jamais publié. Voici une implémentation suggérée de votre méthode:

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

Autres conseils

Vous pouvez utiliser NSWorkspace pour que le système devine l'UTI d'un fichier.

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

Suggérez aux gens de changer le retour en [mimeType autorelease]; - Certains d'entre nous utilisent encore les anciennes méthodes!

Et merci! Ce fut une grande aide.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top