Pergunta

A minha aplicação é um visualizador para um formato personalizado, um arquivo zip com um manifesto XML bem definido e recursos, como imagens e filmes. Eu uso zlib para abrir o arquivo zip na memória e, em seguida, proceder à visualização disse recursos.

Um problema que eu tive já em é que eu sou incapaz de exibir corretamente vídeos, aparentemente porque QTMovie não pode determinar o tipo MIME. Filme carregado a partir do arquivo ([QTMovie movieWithFile]) funciona perfeitamente. Carregado a partir da memória ([QTMovie movieWithData]) se recusa a trabalhar.

Isso faz sentido, porque falta a extensão do arquivo, QTMovie não pode determinar a informação mime-type. Depois de um pouco de pesquisa, eu recorreu ao uso de QTDataReference na seguinte mannner:

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

Isso funciona muito bem, no entanto hardcoding MIMEType está longe de ser ideal. Eu tenho acesso ao nome do arquivo e a extensão, por isso eu tentei encontrar o tipo mime usando UTI (graças aos povos agradáveis ??sobre #macdev):

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

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

Este, porém, não funciona. Claramente, há um banco de dados interno OS X de extensões e correspondentes tipos MIME, em algum lugar. Caso contrário filmes a partir de disco não iria funcionar. Como faço para obter acesso a ele?

Obrigado!

Foi útil?

Solução

O problema seu ter é que m4v e m4p não tem um tipo de MIME registrados Launch Services (provavelmente porque o tipo de mime para m4v e m4p não é padrão). Em qualquer caso, o que você provavelmente deve fazer é casos de ponta punho como este e, em seguida, verificar se há nil quando a função retorna (no caso a extensão é tanto não registrado e não tratado por você).

A outra coisa é que você está com vazamento de memória com o seu uso atual. Eu estou supondo que você está usando a coleta de lixo, mas a primeira chamada cria um CFString que nunca é liberado. Aqui está uma implementação sugerida do seu método:

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

Outras dicas

Você pode usar NSWorkspace ter a UTI palpite sistema de um arquivo.

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

sugerem que as pessoas mudam o retorno à [mimeType autorelease]; - alguns de nós ainda usam as antigas formas

E muito obrigado! Esta foi uma grande ajuda.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top