Commit ed10876a authored by Pierre d'Herbemont's avatar Pierre d'Herbemont

Sources/VLCMediaPlayer.m: Position getters and setters.

parent 29136ffc
......@@ -24,6 +24,8 @@
#import <Cocoa/Cocoa.h>
#import "VLCMedia.h"
#import "VLCVideoView.h"
#import "VLCTime.h"
/* Notification Messages */
extern NSString * VLCMediaPlayerTimeChanged;
......@@ -61,6 +63,8 @@ extern NSString *VLCMediaPlayerStateToString(VLCMediaPlayerState state);
void *instance; // Internal
VLCMedia *media; //< Current media being played
VLCTime *cachedTime;
VLCMediaPlayerState cachedState;
float position;
}
/* Initializers */
......@@ -181,4 +185,11 @@ extern NSString *VLCMediaPlayerStateToString(VLCMediaPlayerState state);
* \see VLCMediaState
*/
- (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
......@@ -33,6 +33,20 @@
NSString *VLCMediaPlayerTimeChanged = @"VLCMediaPlayerTimeChanged";
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 */
static void HandleMediaInstanceVolumeChanged(const libvlc_event_t *event, void *self)
{
......@@ -44,9 +58,10 @@ static void HandleMediaInstanceVolumeChanged(const libvlc_event_t *event, void *
static void HandleMediaTimeChanged(const libvlc_event_t * event, void * self)
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSLog(@"time!");
[[VLCEventManager sharedManager] callOnMainThreadObject:self
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
withDelegateMethod:@selector(mediaPlayerTimeChanged:)
......@@ -54,35 +69,61 @@ static void HandleMediaTimeChanged(const libvlc_event_t * event, void * self)
[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)
{
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
withDelegateMethod:@selector(mediaPlayerStateChanged:)
withNotificationName: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];
[pool release];
}
// TODO: Documentation
@interface VLCMediaPlayer (Private)
- (void)registerObservers;
- (void)unregisterObservers;
- (void)mediaPlayerTimeChanged:(NSNumber *)newTime;
- (void)mediaPlayerPositionChanged:(NSNumber *)newTime;
- (void)mediaPlayerStateChanged:(NSNumber *)newState;
@end
@implementation VLCMediaPlayer
+ (void)initialize {
[self setKeys:[NSArray arrayWithObject:@"state"] triggerChangeNotificationsForDependentKey:@"playing"];
}
- (id)init
{
return [self initWithVideoView:nil];
......@@ -95,6 +136,9 @@ NSString *VLCMediaPlayerStateToString(VLCMediaPlayerState state)
delegate = nil;
media = nil;
cachedTime = [[VLCTime nullTime] retain];
position = 0.0f;
cachedState = VLCMediaPlayerStateStopped;
// 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
// instance
......@@ -110,14 +154,27 @@ NSString *VLCMediaPlayerStateToString(VLCMediaPlayerState state)
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
{
// 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?
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);
// Get rid of everything else
......@@ -483,20 +540,18 @@ static const VLCMediaPlayerState libvlc_to_local_state[] =
- (VLCMediaPlayerState)state
{
// If there is no instance, assume that we're in a stopped state
if (!instance)
return VLCMediaPlayerStateStopped;
return cachedState;
}
- (float)position
{
return position;
}
- (void)setPosition:(float)newPosition
{
libvlc_exception_t ex;
libvlc_exception_init( &ex );
libvlc_state_t libvlc_state = libvlc_media_instance_get_state( (libvlc_media_instance_t *)instance, &ex );
if (libvlc_exception_raised( &ex ))
{
libvlc_exception_clear( &ex );
return VLCMediaPlayerStateError;
}
else
return libvlc_to_local_state[libvlc_state];
libvlc_media_instance_set_position( instance, newPosition, &ex );
quit_on_exception( &ex );
}
@end
......@@ -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_MediaInstanceReachedEnd, HandleMediaInstanceStateChanged, self, &ex );
/* 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 );
}
......@@ -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_MediaInstanceReachedEnd, HandleMediaInstanceStateChanged, 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
{
[self willChangeValueForKey:@"time"];
......@@ -531,4 +589,20 @@ static const VLCMediaPlayerState libvlc_to_local_state[] =
cachedTime = [[VLCTime timeWithNumber:newTime] retain];
[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
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