Commit 5f60e376 authored by Pierre d'Herbemont's avatar Pierre d'Herbemont

Sources/VLCMediaPlayer.m: Position getters and setters.

parent acd2d9b6
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#import "VLCMedia.h" #import "VLCMedia.h"
#import "VLCVideoView.h"
#import "VLCTime.h"
/* Notification Messages */ /* Notification Messages */
extern NSString * VLCMediaPlayerTimeChanged; extern NSString * VLCMediaPlayerTimeChanged;
...@@ -61,6 +63,8 @@ extern NSString *VLCMediaPlayerStateToString(VLCMediaPlayerState state); ...@@ -61,6 +63,8 @@ extern NSString *VLCMediaPlayerStateToString(VLCMediaPlayerState state);
void *instance; // Internal void *instance; // Internal
VLCMedia *media; //< Current media being played VLCMedia *media; //< Current media being played
VLCTime *cachedTime; VLCTime *cachedTime;
VLCMediaPlayerState cachedState;
float position;
} }
/* Initializers */ /* Initializers */
...@@ -181,4 +185,11 @@ extern NSString *VLCMediaPlayerStateToString(VLCMediaPlayerState state); ...@@ -181,4 +185,11 @@ extern NSString *VLCMediaPlayerStateToString(VLCMediaPlayerState state);
* \see VLCMediaState * \see VLCMediaState
*/ */
- (VLCMediaPlayerState)state; - (VLCMediaPlayerState)state;
/**
* Returns the receiver's position in the reading.
* \return A number between 0 and 1. indicating the position
*/
- (float)position;
- (void)setPosition:(float)newPosition;
@end @end
...@@ -33,6 +33,20 @@ ...@@ -33,6 +33,20 @@
NSString *VLCMediaPlayerTimeChanged = @"VLCMediaPlayerTimeChanged"; NSString *VLCMediaPlayerTimeChanged = @"VLCMediaPlayerTimeChanged";
NSString *VLCMediaPlayerStateChanged = @"VLCMediaPlayerStateChanged"; NSString *VLCMediaPlayerStateChanged = @"VLCMediaPlayerStateChanged";
NSString *VLCMediaPlayerStateToString(VLCMediaPlayerState state)
{
static NSString *stateToStrings[] = {
[VLCMediaPlayerStateStopped] = @"VLCMediaPlayerStateStopped",
[VLCMediaPlayerStateOpening] = @"VLCMediaPlayerStateOpening",
[VLCMediaPlayerStateBuffering] = @"VLCMediaPlayerStateBuffering",
[VLCMediaPlayerStateEnded] = @"VLCMediaPlayerStateEnded",
[VLCMediaPlayerStateError] = @"VLCMediaPlayerStateError",
[VLCMediaPlayerStatePlaying] = @"VLCMediaPlayerStatePlaying",
[VLCMediaPlayerStatePaused] = @"VLCMediaPlayerStatePaused"
};
return stateToStrings[state];
}
/* libvlc event callback */ /* libvlc event callback */
static void HandleMediaInstanceVolumeChanged(const libvlc_event_t *event, void *self) static void HandleMediaInstanceVolumeChanged(const libvlc_event_t *event, void *self)
{ {
...@@ -44,9 +58,10 @@ static void HandleMediaInstanceVolumeChanged(const libvlc_event_t *event, void * ...@@ -44,9 +58,10 @@ static void HandleMediaInstanceVolumeChanged(const libvlc_event_t *event, void *
static void HandleMediaTimeChanged(const libvlc_event_t * event, void * self) static void HandleMediaTimeChanged(const libvlc_event_t * event, void * self)
{ {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSLog(@"time!");
[[VLCEventManager sharedManager] callOnMainThreadObject:self [[VLCEventManager sharedManager] callOnMainThreadObject:self
withMethod:@selector(mediaPlayerTimeChanged:) withMethod:@selector(mediaPlayerTimeChanged:)
withArgumentAsObject:[NSNumber numberWithLongLong:event->u.media_instance_position_changed.new_position]]; withArgumentAsObject:[NSNumber numberWithLongLong:event->u.media_instance_time_changed.new_time]];
[[VLCEventManager sharedManager] callOnMainThreadDelegateOfObject:self [[VLCEventManager sharedManager] callOnMainThreadDelegateOfObject:self
withDelegateMethod:@selector(mediaPlayerTimeChanged:) withDelegateMethod:@selector(mediaPlayerTimeChanged:)
...@@ -54,35 +69,61 @@ static void HandleMediaTimeChanged(const libvlc_event_t * event, void * self) ...@@ -54,35 +69,61 @@ static void HandleMediaTimeChanged(const libvlc_event_t * event, void * self)
[pool release]; [pool release];
} }
static void HandleMediaPositionChanged(const libvlc_event_t * event, void * self)
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
[[VLCEventManager sharedManager] callOnMainThreadObject:self
withMethod:@selector(mediaPlayerPositionChanged:)
withArgumentAsObject:[NSNumber numberWithFloat:event->u.media_instance_position_changed.new_position]];
[pool release];
}
static void HandleMediaInstanceStateChanged(const libvlc_event_t *event, void *self) static void HandleMediaInstanceStateChanged(const libvlc_event_t *event, void *self)
{ {
VLCMediaPlayerState newState;
if( event->type == libvlc_MediaInstancePlayed )
newState = VLCMediaPlayerStatePlaying;
else if( event->type == libvlc_MediaInstancePaused )
newState = VLCMediaPlayerStatePaused;
else if( event->type == libvlc_MediaInstanceReachedEnd )
newState = VLCMediaPlayerStateStopped;
else
{
NSLog(@"%s: Unknown event", __FUNCTION__);
return;
}
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
[[VLCEventManager sharedManager] callOnMainThreadObject:self
withMethod:@selector(mediaPlayerStateChanged:)
withArgumentAsObject:[NSNumber numberWithInt:newState]];
[[VLCEventManager sharedManager] callOnMainThreadDelegateOfObject:self [[VLCEventManager sharedManager] callOnMainThreadDelegateOfObject:self
withDelegateMethod:@selector(mediaPlayerStateChanged:) withDelegateMethod:@selector(mediaPlayerStateChanged:)
withNotificationName:VLCMediaPlayerStateChanged]; withNotificationName:VLCMediaPlayerStateChanged];
}
NSString *VLCMediaPlayerStateToString(VLCMediaPlayerState state) [pool release];
{
static NSString *stateToStrings[] = {
[VLCMediaPlayerStateStopped] = @"VLCMediaPlayerStateStopped",
[VLCMediaPlayerStateOpening] = @"VLCMediaPlayerStateOpening",
[VLCMediaPlayerStateBuffering] = @"VLCMediaPlayerStateBuffering",
[VLCMediaPlayerStateEnded] = @"VLCMediaPlayerStateEnded",
[VLCMediaPlayerStateError] = @"VLCMediaPlayerStateError",
[VLCMediaPlayerStatePlaying] = @"VLCMediaPlayerStatePlaying",
[VLCMediaPlayerStatePaused] = @"VLCMediaPlayerStatePaused"
};
return stateToStrings[state];
} }
// TODO: Documentation // TODO: Documentation
@interface VLCMediaPlayer (Private) @interface VLCMediaPlayer (Private)
- (void)registerObservers; - (void)registerObservers;
- (void)unregisterObservers; - (void)unregisterObservers;
- (void)mediaPlayerTimeChanged:(NSNumber *)newTime; - (void)mediaPlayerTimeChanged:(NSNumber *)newTime;
- (void)mediaPlayerPositionChanged:(NSNumber *)newTime;
- (void)mediaPlayerStateChanged:(NSNumber *)newState;
@end @end
@implementation VLCMediaPlayer @implementation VLCMediaPlayer
+ (void)initialize {
[self setKeys:[NSArray arrayWithObject:@"state"] triggerChangeNotificationsForDependentKey:@"playing"];
}
- (id)init - (id)init
{ {
return [self initWithVideoView:nil]; return [self initWithVideoView:nil];
...@@ -95,6 +136,9 @@ NSString *VLCMediaPlayerStateToString(VLCMediaPlayerState state) ...@@ -95,6 +136,9 @@ NSString *VLCMediaPlayerStateToString(VLCMediaPlayerState state)
delegate = nil; delegate = nil;
media = nil; media = nil;
cachedTime = [[VLCTime nullTime] retain]; cachedTime = [[VLCTime nullTime] retain];
position = 0.0f;
cachedState = VLCMediaPlayerStateStopped;
// Create a media instance, it doesn't matter what library we start off with // Create a media instance, it doesn't matter what library we start off with
// it will change depending on the media descriptor provided to the media // it will change depending on the media descriptor provided to the media
// instance // instance
...@@ -110,14 +154,27 @@ NSString *VLCMediaPlayerStateToString(VLCMediaPlayerState state) ...@@ -110,14 +154,27 @@ NSString *VLCMediaPlayerStateToString(VLCMediaPlayerState state)
return self; return self;
} }
- (void)release
{
@synchronized(self)
{
if([self retainCount] <= 1)
{
/* 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 */
[self unregisterObservers];
}
[super release];
}
}
- (void)dealloc - (void)dealloc
{ {
// Always get rid of the delegate first so we can stop sending messages to it // Always get rid of the delegate first so we can stop sending messages to it
// TODO: Should we tell the delegate that we're shutting down? // TODO: Should we tell the delegate that we're shutting down?
delegate = nil; delegate = nil;
// Next get rid of the event managers so we can stop trapping events
[self unregisterObservers];
libvlc_media_instance_release((libvlc_media_instance_t *)instance); libvlc_media_instance_release((libvlc_media_instance_t *)instance);
// Get rid of everything else // Get rid of everything else
...@@ -483,20 +540,18 @@ static const VLCMediaPlayerState libvlc_to_local_state[] = ...@@ -483,20 +540,18 @@ static const VLCMediaPlayerState libvlc_to_local_state[] =
- (VLCMediaPlayerState)state - (VLCMediaPlayerState)state
{ {
// If there is no instance, assume that we're in a stopped state return cachedState;
if (!instance) }
return VLCMediaPlayerStateStopped; - (float)position
{
return position;
}
- (void)setPosition:(float)newPosition
{
libvlc_exception_t ex; libvlc_exception_t ex;
libvlc_exception_init( &ex ); libvlc_exception_init( &ex );
libvlc_state_t libvlc_state = libvlc_media_instance_get_state( (libvlc_media_instance_t *)instance, &ex ); libvlc_media_instance_set_position( instance, newPosition, &ex );
if (libvlc_exception_raised( &ex )) quit_on_exception( &ex );
{
libvlc_exception_clear( &ex );
return VLCMediaPlayerStateError;
}
else
return libvlc_to_local_state[libvlc_state];
} }
@end @end
...@@ -512,7 +567,8 @@ static const VLCMediaPlayerState libvlc_to_local_state[] = ...@@ -512,7 +567,8 @@ static const VLCMediaPlayerState libvlc_to_local_state[] =
libvlc_event_attach( p_em, libvlc_MediaInstancePaused, HandleMediaInstanceStateChanged, self, &ex ); libvlc_event_attach( p_em, libvlc_MediaInstancePaused, HandleMediaInstanceStateChanged, self, &ex );
libvlc_event_attach( p_em, libvlc_MediaInstanceReachedEnd, HandleMediaInstanceStateChanged, self, &ex ); libvlc_event_attach( p_em, libvlc_MediaInstanceReachedEnd, HandleMediaInstanceStateChanged, self, &ex );
/* FIXME: We may want to turn that off when none is interested by that */ /* FIXME: We may want to turn that off when none is interested by that */
libvlc_event_attach( p_em, libvlc_MediaInstancePositionChanged, HandleMediaTimeChanged, self, &ex ); libvlc_event_attach( p_em, libvlc_MediaInstancePositionChanged, HandleMediaPositionChanged, self, &ex );
libvlc_event_attach( p_em, libvlc_MediaInstanceTimeChanged, HandleMediaTimeChanged, self, &ex );
quit_on_exception( &ex ); quit_on_exception( &ex );
} }
...@@ -523,7 +579,9 @@ static const VLCMediaPlayerState libvlc_to_local_state[] = ...@@ -523,7 +579,9 @@ static const VLCMediaPlayerState libvlc_to_local_state[] =
libvlc_event_detach( p_em, libvlc_MediaInstancePaused, HandleMediaInstanceStateChanged, self, NULL ); libvlc_event_detach( p_em, libvlc_MediaInstancePaused, HandleMediaInstanceStateChanged, self, NULL );
libvlc_event_detach( p_em, libvlc_MediaInstanceReachedEnd, HandleMediaInstanceStateChanged, self, NULL ); libvlc_event_detach( p_em, libvlc_MediaInstanceReachedEnd, HandleMediaInstanceStateChanged, self, NULL );
libvlc_event_detach( p_em, libvlc_MediaInstancePositionChanged, HandleMediaTimeChanged, self, NULL ); libvlc_event_detach( p_em, libvlc_MediaInstancePositionChanged, HandleMediaTimeChanged, self, NULL );
libvlc_event_detach( p_em, libvlc_MediaInstanceTimeChanged, HandleMediaTimeChanged, self, NULL );
} }
- (void)mediaPlayerTimeChanged:(NSNumber *)newTime - (void)mediaPlayerTimeChanged:(NSNumber *)newTime
{ {
[self willChangeValueForKey:@"time"]; [self willChangeValueForKey:@"time"];
...@@ -531,4 +589,20 @@ static const VLCMediaPlayerState libvlc_to_local_state[] = ...@@ -531,4 +589,20 @@ static const VLCMediaPlayerState libvlc_to_local_state[] =
cachedTime = [[VLCTime timeWithNumber:newTime] retain]; cachedTime = [[VLCTime timeWithNumber:newTime] retain];
[self didChangeValueForKey:@"time"]; [self didChangeValueForKey:@"time"];
} }
- (void)mediaPlayerPositionChanged:(NSNumber *)newPosition
{
if( [newPosition floatValue] - position < 0.005 && position - [newPosition floatValue] < 0.005 )
return; /* Forget that, this is too much precision for our uses */
[self willChangeValueForKey:@"position"];
position = ((float)((int)([newPosition floatValue]*1000)))/1000.;
[self didChangeValueForKey:@"position"];
}
- (void)mediaPlayerStateChanged:(NSNumber *)newState
{
[self willChangeValueForKey:@"state"];
cachedState = [newState intValue];
[self didChangeValueForKey:@"state"];
}
@end @end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment