Вопрос

Мое приложение представляет собой программу просмотра пользовательского формата, zip-файл с четко определенным XML-манифестом и ресурсами, такими как изображения и фильмы.Я использую zlib, чтобы открыть zip-файл в памяти, а затем приступить к отображению указанных ресурсов.

Одна из проблем, с которой я столкнулся, заключается в том, что я не могу правильно отображать видео, по-видимому, потому, что 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 далеко от идеала.У меня есть доступ к имени файла и расширению, поэтому я попытался найти mime-тип с помощью UTI (спасибо ребятам из #macdev):

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

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

Однако это не работает.Очевидно, что где-то существует внутренняя база данных расширений и соответствующих mime-типов OS X.В противном случае фильмы с диска не будут работать.Как мне получить к нему доступ?

Спасибо!

Это было полезно?

Решение

Проблема, с которой вы столкнулись, заключается в том, что m4v и m4p не имеют типов mime, зарегистрированных в службах запуска (вероятно, потому, что тип mime для m4v и m4p не является стандартным).В любом случае вам, вероятно, следует обрабатывать такие крайние случаи, а затем проверять ноль, когда функция возвращает значение (в случае, если расширение не зарегистрировано и не обрабатывается вами).

Другое дело, что при текущем использовании у вас происходит утечка памяти.Я предполагаю, что вы используете сборку мусора, но первый вызов создает 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;
}

Другие советы

Вы можете использовать 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;
}

Предложите людям изменить возврат на [mimeType autorelease];- некоторые из нас до сих пор используют древние способы!

И спасибо!Это была большая помощь.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top