X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=projects%2Fmacosx%2Fframework%2FSources%2FVLCMedia.m;h=3f2f1612539d155462adc1802ee699cbc851a27f;hb=1609af14267518bf7c2c87a64755a90e4a23c12c;hp=5e96e23d422bde2051c82b504244e07fe600e8db;hpb=4a19225407971ebbbd26840072d62ededc782d0e;p=vlc diff --git a/projects/macosx/framework/Sources/VLCMedia.m b/projects/macosx/framework/Sources/VLCMedia.m index 5e96e23d42..3f2f161253 100644 --- a/projects/macosx/framework/Sources/VLCMedia.m +++ b/projects/macosx/framework/Sources/VLCMedia.m @@ -1,5 +1,5 @@ /***************************************************************************** - * VLCMedia.m: VLC.framework VLCMedia implementation + * VLCMedia.m: VLCKit.framework VLCMedia implementation ***************************************************************************** * Copyright (C) 2007 Pierre d'Herbemont * Copyright (C) 2007 the VideoLAN team @@ -104,8 +104,8 @@ static inline VLCMediaState LibVLCStateToMediaState( libvlc_state_t state ) */ static void HandleMediaMetaChanged(const libvlc_event_t * event, void * self) { - if( event->u.media_descriptor_meta_changed.meta_type == libvlc_meta_Publisher || - event->u.media_descriptor_meta_changed.meta_type == libvlc_meta_NowPlaying ) + if( event->u.media_meta_changed.meta_type == libvlc_meta_Publisher || + event->u.media_meta_changed.meta_type == libvlc_meta_NowPlaying ) { /* Skip those meta. We don't really care about them for now. * And they occure a lot */ @@ -114,29 +114,29 @@ static void HandleMediaMetaChanged(const libvlc_event_t * event, void * self) NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; [[VLCEventManager sharedManager] callOnMainThreadObject:self withMethod:@selector(metaChanged:) - withArgumentAsObject:[VLCMedia metaTypeToString:event->u.media_descriptor_meta_changed.meta_type]]; + withArgumentAsObject:[VLCMedia metaTypeToString:event->u.media_meta_changed.meta_type]]; [pool release]; } -//static void HandleMediaDurationChanged(const libvlc_event_t * event, void * self) -//{ -// NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; -// -// [[VLCEventManager sharedManager] callOnMainThreadObject:self -// withMethod:@selector(setLength:) -// withArgumentAsObject:[VLCTime timeWithNumber: -// [NSNumber numberWithLongLong:event->u.media_descriptor_duration_changed.new_duration]]]; -// [pool release]; -//} +static void HandleMediaDurationChanged(const libvlc_event_t * event, void * self) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + [[VLCEventManager sharedManager] callOnMainThreadObject:self + withMethod:@selector(setLength:) + withArgumentAsObject:[VLCTime timeWithNumber: + [NSNumber numberWithLongLong:event->u.media_duration_changed.new_duration]]]; + [pool release]; +} static void HandleMediaStateChanged(const libvlc_event_t * event, void * self) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - + [[VLCEventManager sharedManager] callOnMainThreadObject:self withMethod:@selector(setStateAsNumber:) withArgumentAsObject:[NSNumber numberWithInt: - LibVLCStateToMediaState(event->u.media_descriptor_state_changed.new_state)]]; + LibVLCStateToMediaState(event->u.media_state_changed.new_state)]]; [pool release]; } @@ -168,26 +168,21 @@ static void HandleMediaSubItemAdded(const libvlc_event_t * event, void * self) return [[[VLCMedia alloc] initAsNodeWithName:aName] autorelease]; } -- (id)initWithURL:(NSURL *)anURL +- (id)initWithPath:(NSString *)aPath { - return [self initWithPath:[anURL path]]; + return [self initWithURL:[NSURL fileURLWithPath:aPath isDirectory:NO]]; } -- (id)initWithPath:(NSString *)aPath -{ +- (id)initWithURL:(NSURL *)anURL +{ if (self = [super init]) { - libvlc_exception_t ex; - libvlc_exception_init(&ex); - - p_md = libvlc_media_descriptor_new([VLCLibrary sharedInstance], - [aPath UTF8String], - &ex); - catch_exception(&ex); - + p_md = libvlc_media_new_location([VLCLibrary sharedInstance], + [[anURL absoluteString] UTF8String]); + delegate = nil; metaDictionary = [[NSMutableDictionary alloc] initWithCapacity:3]; - + // This value is set whenever the demuxer figures out what the length is. // TODO: Easy way to tell the length of the movie without having to instiate the demuxer. Maybe cached info? length = nil; @@ -198,29 +193,31 @@ static void HandleMediaSubItemAdded(const libvlc_event_t * event, void * self) } - (id)initAsNodeWithName:(NSString *)aName -{ +{ if (self = [super init]) { - libvlc_exception_t ex; - libvlc_exception_init(&ex); - - p_md = libvlc_media_descriptor_new_as_node([VLCLibrary sharedInstance], - [aName UTF8String], - &ex); - catch_exception(&ex); + p_md = libvlc_media_new_as_node([VLCLibrary sharedInstance], + [aName UTF8String]); delegate = nil; metaDictionary = [[NSMutableDictionary alloc] initWithCapacity:3]; - + // This value is set whenever the demuxer figures out what the length is. // TODO: Easy way to tell the length of the movie without having to instiate the demuxer. Maybe cached info? length = nil; - + [self initInternalMediaDescriptor]; } return self; } +- (void)setValue:(NSString *)value forMeta:(NSString *)meta +{ + libvlc_meta_t metaName = [VLCMedia stringToMetaType:meta]; + NSAssert(metaName >= 0, @"Invalid meta"); + libvlc_media_set_meta(p_md, metaName, [value UTF8String]); +} + - (void)release { @synchronized(self) @@ -230,11 +227,11 @@ static void HandleMediaSubItemAdded(const libvlc_event_t * event, void * self) /* We must make sure we won't receive new event after an upcoming dealloc * We also may receive a -retain in some event callback that may occcur * Before libvlc_event_detach. So this can't happen in dealloc */ - libvlc_event_manager_t * p_em = libvlc_media_descriptor_event_manager(p_md, NULL); - libvlc_event_detach(p_em, libvlc_MediaDescriptorMetaChanged, HandleMediaMetaChanged, self, NULL); -// libvlc_event_detach(p_em, libvlc_MediaDescriptorDurationChanged, HandleMediaDurationChanged, self, NULL); - libvlc_event_detach(p_em, libvlc_MediaDescriptorStateChanged, HandleMediaStateChanged, self, NULL); - libvlc_event_detach(p_em, libvlc_MediaDescriptorSubItemAdded, HandleMediaSubItemAdded, self, NULL); + libvlc_event_manager_t * p_em = libvlc_media_event_manager(p_md); + libvlc_event_detach(p_em, libvlc_MediaMetaChanged, HandleMediaMetaChanged, self); + libvlc_event_detach(p_em, libvlc_MediaDurationChanged, HandleMediaDurationChanged, self); + libvlc_event_detach(p_em, libvlc_MediaStateChanged, HandleMediaStateChanged, self); + libvlc_event_detach(p_em, libvlc_MediaSubItemAdded, HandleMediaSubItemAdded, self); } [super release]; } @@ -245,13 +242,12 @@ static void HandleMediaSubItemAdded(const libvlc_event_t * event, void * self) // Testing to see if the pointer exists is not required, if the pointer is null // then the release message is not sent to it. delegate = nil; - [self setLength:nil]; - + [length release]; [url release]; [subitems release]; [metaDictionary release]; - libvlc_media_descriptor_release( p_md ); + libvlc_media_release( p_md ); [super dealloc]; } @@ -275,17 +271,18 @@ static void HandleMediaSubItemAdded(const libvlc_event_t * event, void * self) - (VLCTime *)length { - if (!length) + if (!length) { // Try figuring out what the length is - long long duration = libvlc_media_descriptor_get_duration( p_md, NULL ); - if (duration > -1) + long long duration = libvlc_media_get_duration( p_md ); + if (duration > -1) { - [self setLength:[VLCTime timeWithNumber:[NSNumber numberWithLongLong:duration]]]; + length = [[VLCTime timeWithNumber:[NSNumber numberWithLongLong:duration]] retain]; return [[length retain] autorelease]; - } + } + return [VLCTime nullTime]; } - return [VLCTime nullTime]; + return [[length retain] autorelease]; } - (VLCTime *)lengthWaitUntilDate:(NSDate *)aDate @@ -294,11 +291,15 @@ static void HandleMediaSubItemAdded(const libvlc_event_t * event, void * self) if (!length) { - while (!length && ![self isPreparsed] && [aDate timeIntervalSinceNow] > 0) + // Force preparsing of this item. + [self length]; + + // wait until we are preparsed + while (!length && ![self isParsed] && [aDate timeIntervalSinceNow] > 0) { usleep( thread_sleep ); } - + // So we're done waiting, but sometimes we trap the fact that the parsing // was done before the length gets assigned, so lets go ahead and assign // it ourselves. @@ -309,9 +310,9 @@ static void HandleMediaSubItemAdded(const libvlc_event_t * event, void * self) return [[length retain] autorelease]; } -- (BOOL)isPreparsed +- (BOOL)isParsed { - return libvlc_media_descriptor_is_preparsed( p_md, NULL ); + return libvlc_media_is_parsed( p_md ); } @synthesize url; @@ -335,30 +336,28 @@ static void HandleMediaSubItemAdded(const libvlc_event_t * event, void * self) { if (self = [super init]) { - libvlc_exception_t ex; - libvlc_exception_init( &ex ); - - libvlc_media_descriptor_retain( md ); + libvlc_media_retain( md ); p_md = md; - + metaDictionary = [[NSMutableDictionary alloc] initWithCapacity:3]; [self initInternalMediaDescriptor]; } return self; } -- (void *)libVLCMediaDescriptor +- (void *)libVLCMediaDescriptor { return p_md; } + (id)mediaWithMedia:(VLCMedia *)media andLibVLCOptions:(NSDictionary *)options { - libvlc_media_descriptor_t * p_md; - p_md = libvlc_media_descriptor_duplicate( [media libVLCMediaDescriptor] ); + libvlc_media_t * p_md; + p_md = libvlc_media_duplicate( [media libVLCMediaDescriptor] ); + for( NSString * key in [options allKeys] ) { - libvlc_media_descriptor_add_option(p_md, [[NSString stringWithFormat:@"%@=#%@", key, [options objectForKey:key]] UTF8String], NULL); + libvlc_media_add_option(p_md, [[NSString stringWithFormat:@"%@=#%@", key, [options objectForKey:key]] UTF8String]); } return [VLCMedia mediaWithLibVLCMediaDescriptor:p_md]; } @@ -427,30 +426,22 @@ static void HandleMediaSubItemAdded(const libvlc_event_t * event, void * self) - (void)initInternalMediaDescriptor { - libvlc_exception_t ex; - libvlc_exception_init( &ex ); - - artFetched = NO; - - char * p_url = libvlc_media_descriptor_get_mrl( p_md, &ex ); - catch_exception( &ex ); + char * p_url = libvlc_media_get_mrl( p_md ); url = [[NSURL URLWithString:[NSString stringWithUTF8String:p_url]] retain]; if( !url ) /* Attempt to interpret as a file path then */ url = [[NSURL fileURLWithPath:[NSString stringWithUTF8String:p_url]] retain]; free( p_url ); - libvlc_media_descriptor_set_user_data( p_md, (void*)self, &ex ); - catch_exception( &ex ); + libvlc_media_set_user_data( p_md, (void*)self ); - libvlc_event_manager_t * p_em = libvlc_media_descriptor_event_manager( p_md, &ex ); - libvlc_event_attach(p_em, libvlc_MediaDescriptorMetaChanged, HandleMediaMetaChanged, self, &ex); -// libvlc_event_attach(p_em, libvlc_MediaDescriptorDurationChanged, HandleMediaDurationChanged, self, &ex); - libvlc_event_attach(p_em, libvlc_MediaDescriptorStateChanged, HandleMediaStateChanged, self, &ex); - libvlc_event_attach(p_em, libvlc_MediaDescriptorSubItemAdded, HandleMediaSubItemAdded, self, &ex); - catch_exception( &ex ); - - libvlc_media_list_t * p_mlist = libvlc_media_descriptor_subitems( p_md, NULL ); + libvlc_event_manager_t * p_em = libvlc_media_event_manager( p_md ); + libvlc_event_attach(p_em, libvlc_MediaMetaChanged, HandleMediaMetaChanged, self); + libvlc_event_attach(p_em, libvlc_MediaDurationChanged, HandleMediaDurationChanged, self); + libvlc_event_attach(p_em, libvlc_MediaStateChanged, HandleMediaStateChanged, self); + libvlc_event_attach(p_em, libvlc_MediaSubItemAdded, HandleMediaSubItemAdded, self); + + libvlc_media_list_t * p_mlist = libvlc_media_subitems( p_md ); if (!p_mlist) subitems = nil; @@ -460,28 +451,24 @@ static void HandleMediaSubItemAdded(const libvlc_event_t * event, void * self) libvlc_media_list_release( p_mlist ); } - state = LibVLCStateToMediaState(libvlc_media_descriptor_get_state( p_md, NULL )); - - /* Force VLCMetaInformationTitle, that will trigger preparsing - * And all the other meta will be added through the libvlc event system */ - [self fetchMetaInformationFromLibVLCWithType: VLCMetaInformationTitle]; + state = LibVLCStateToMediaState(libvlc_media_get_state( p_md )); } - (void)fetchMetaInformationFromLibVLCWithType:(NSString *)metaType { - char * psz_value = libvlc_media_descriptor_get_meta( p_md, [VLCMedia stringToMetaType:metaType], NULL); + char * psz_value = libvlc_media_get_meta( p_md, [VLCMedia stringToMetaType:metaType] ); NSString * newValue = psz_value ? [NSString stringWithUTF8String: psz_value] : nil; NSString * oldValue = [metaDictionary valueForKey:metaType]; free(psz_value); if ( newValue != oldValue && !(oldValue && newValue && [oldValue compare:newValue] == NSOrderedSame) ) { - if ([metaType isEqualToString:VLCMetaInformationArtworkURL]) + // Only fetch the art if needed. (ie, create the NSImage, if it was requested before) + if (isArtFetched && [metaType isEqualToString:VLCMetaInformationArtworkURL]) { - [NSThread detachNewThreadSelector:@selector(fetchMetaInformationForArtWorkWithURL:) + [NSThread detachNewThreadSelector:@selector(fetchMetaInformationForArtWorkWithURL:) toTarget:self withObject:newValue]; - return; } [metaDictionary setValue:newValue forKeyPath:metaType]; @@ -500,7 +487,7 @@ static void HandleMediaSubItemAdded(const libvlc_event_t * event, void * self) // Don't attempt to fetch artwork from remote. Core will do that alone if ([artUrl isFileURL]) - art = [[[NSImage alloc] initWithContentsOfURL:artUrl] autorelease]; + art = [[[NSImage alloc] initWithContentsOfURL:artUrl] autorelease]; } // If anything was found, lets save it to the meta data dictionary @@ -530,7 +517,7 @@ static void HandleMediaSubItemAdded(const libvlc_event_t * event, void * self) if( subitems ) return; /* Nothing to do */ - libvlc_media_list_t * p_mlist = libvlc_media_descriptor_subitems( p_md, NULL ); + libvlc_media_list_t * p_mlist = libvlc_media_subitems( p_md ); NSAssert( p_mlist, @"The mlist shouldn't be nil, we are receiving a subItemAdded"); @@ -547,12 +534,28 @@ static void HandleMediaSubItemAdded(const libvlc_event_t * event, void * self) - (id)valueForKeyPath:(NSString *)keyPath { - if( ![metaDictionary objectForKey:@"artwork"] && [keyPath isEqualToString:@"metaDictionary.artwork"]) + if( !isArtFetched && [keyPath isEqualToString:@"metaDictionary.artwork"]) { - artFetched = YES; + isArtFetched = YES; /* Force the retrieval of the artwork now that someone asked for it */ [self fetchMetaInformationFromLibVLCWithType: VLCMetaInformationArtworkURL]; } + else if( !areOthersMetaFetched && [keyPath hasPrefix:@"metaDictionary."]) + { + areOthersMetaFetched = YES; + /* Force VLCMetaInformationTitle, that will trigger preparsing + * And all the other meta will be added through the libvlc event system */ + [self fetchMetaInformationFromLibVLCWithType: VLCMetaInformationTitle]; + + } + else if( !isArtURLFetched && [keyPath hasPrefix:@"metaDictionary.artworkURL"]) + { + isArtURLFetched = YES; + /* Force isArtURLFetched, that will trigger artwork download eventually + * And all the other meta will be added through the libvlc event system */ + [self fetchMetaInformationFromLibVLCWithType: VLCMetaInformationArtworkURL]; + } + return [super valueForKeyPath:keyPath]; } @end @@ -567,8 +570,8 @@ static void HandleMediaSubItemAdded(const libvlc_event_t * event, void * self) { if (length && value && [length compare:value] == NSOrderedSame) return; - - [length release]; + + [length release]; length = value ? [value retain] : nil; }