source: branches/CoreData/SapphireFrappliance/Players/SapphireAudioPlayer.m @ 903

Revision 903, 6.5 KB checked in by gbooker, 5 years ago (diff)

Finally made the audio playback functional again. This is still missing the setState:error: selector so it cannot be controlled on later versions of the ATV, but at least it doesn't throw an exception anymore and actually plays.

Also, audio playback is stopped if the user selects some other item from the main menu with ATV Take 2, or be exiting to the main menu on ATV Take 1 or Leopard.

Line 
1/*
2 * SapphireAudioPlayer.m
3 * Sapphire
4 *
5 * Created by Graham Booker on Jul. 28, 2007.
6 * Copyright 2007 Sapphire Development Team and/or www.nanopi.net
7 * All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
10 * General Public License as published by the Free Software Foundation; either version 3 of the License,
11 * or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
14 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15 * Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along with this program; if not,
18 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 */
20
21#import <SapphireCompatClasses/SapphireFrontRowCompat.h>
22#import "SapphireAudioPlayer.h"
23#import "SapphireAudioMedia.h"
24#import "SapphireFileMetaData.h"
25#import "SapphireVideoPlayerController.h"
26#import <QTKit/QTKit.h>
27
28#define SKIP_INTERVAL 0.5
29#define SKIP_ACCELL 0.5 * SKIP_INTERVAL
30
31@interface BRMusicPlayer (compat)
32-(BOOL)setMedia:(id)media inTrackList:(id)trackList error:(NSError **)error;
33-(BOOL)setMediaAtIndex:(long)index inTrackList:(id)trackList error:(NSError **)error;
34@end
35
36
37@interface SapphireAudioPlayer (private)
38- (void)setState:(int)newState;
39- (void)stopUITimer;
40- (void)setSkipTimer;
41- (void)doSkip:(NSTimer *)timer;
42- (void)stopSkip;
43- (void)updateUI:(NSTimer *)Timer;
44@end
45
46@implementation SapphireAudioPlayer
47
48- (id) init {
49        self = [super init];
50        if (self == nil)
51                return nil;
52
53        state = 0;
54
55        return self;
56}
57
58- (void) dealloc
59{
60        [movie release];
61        [self stopUITimer];
62        [self stopSkip];
63        [myMedia release];
64        [myTrackList release];
65        [super dealloc];
66}
67
68- (int)playerState
69{
70        return state;
71}
72
73- (void)setMedia:(SapphireAudioMedia *)media inTracklist:(NSArray *)tracklist error:(NSError * *)error
74{
75        SapphireFrontRowCompatATVVersion version = [SapphireFrontRowCompat atvVersion];
76        if(version >= SapphireFrontRowCompatATVVersion2Dot3)
77                [super setMediaAtIndex:[tracklist indexOfObject:media] inTrackList:tracklist error:error];
78        else if (version >= SapphireFrontRowCompatATVVersion2Dot2)
79                [super setMedia:media inTrackList:tracklist error:error];
80        else
81                [super setMedia:media inTracklist:tracklist error:error];
82       
83        [myMedia release];
84        [myTrackList release];
85        myMedia = [media retain];
86        myTrackList = [tracklist retain];
87       
88        if(error != NULL && *error == nil)
89        {
90                soundState = enablePassthrough([media fileMetaData]);
91                movie = [[QTMovie alloc] initWithURL:[NSURL URLWithString:[media mediaURL]] error:error];
92                [media setMovie:movie];
93                [self setElapsedPlaybackTime:[media bookmarkTimeInSeconds]];
94        }
95        [[NSNotificationCenter defaultCenter] postNotificationName:kBRMediaPlayerCurrentAssetChanged object:media];
96        [[NSNotificationCenter defaultCenter] postNotificationName:@"BRMPCurrentAssetChanged" object:media];
97}
98
99- (SapphireAudioMedia *)media
100{
101        return myMedia;
102}
103
104- (NSArray *)tracklist
105{
106        return myTrackList;
107}
108
109- (float)elapsedPlaybackTime
110{
111        QTTime current = [movie currentTime];
112        double ret = 0.0;
113        QTGetTimeInterval(current, &ret);
114        return (float)ret;
115}
116
117- (double)elapsedTime
118{
119        return [self elapsedPlaybackTime];
120}
121
122- (void)setElapsedPlaybackTime:(float)time
123{
124        QTTime newTime = QTMakeTimeWithTimeInterval((double)time);
125        [movie setCurrentTime:newTime];
126        [self updateUI:nil];
127}
128
129- (double)trackDuration
130{
131        QTTime duration = [movie duration];
132        double ret = 0.0;
133        QTGetTimeInterval(duration, &ret);
134        return (float)ret;
135}
136
137- (NSString *)currentChapterTitle
138{
139        return [movie attributeForKey:QTMovieDisplayNameAttribute];
140}
141
142- (BOOL)initiatePlayback:(NSError * *)error
143{
144        [movie stop];
145        [movie gotoBeginning];
146        return YES;
147}
148
149-(void)setState:(int)newState error:(NSError **)error
150{
151        NSLog(@"I was told to go into state %d", newState);
152}
153
154- (void)setState:(int)newState
155{
156        state = newState;
157        [[NSNotificationCenter defaultCenter] postNotificationName:@"BRMPStateChanged" object:self];
158        [[NSNotificationCenter defaultCenter] postNotificationName:kBRMediaPlayerStateChanged object:self];
159}
160
161- (void)play
162{
163        id media = [self media];
164        [[NSNotificationCenter defaultCenter] postNotificationName:kBRMediaPlayerCurrentAssetChanged object:media];
165        [[NSNotificationCenter defaultCenter] postNotificationName:@"BRMPCurrentAssetChanged" object:media];
166        [self stopSkip];
167        updateTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateUI:) userInfo:nil repeats:YES];
168        [self setState:3];
169        [movie play];
170}
171
172- (void)pause
173{
174        [self stopSkip];
175        [self stopUITimer];
176        [self setState:1];
177        [movie stop];
178}
179
180- (void)stop
181{
182        [self stopSkip];
183        [self stopUITimer];
184        [self setState:0];
185        [movie stop];
186        SapphireFileMetaData *file = [(SapphireAudioMedia *)[self media] fileMetaData];
187        float elapsed = [self elapsedPlaybackTime];
188        float duration = [self trackDuration];
189        if(elapsed >= duration)
190                [file setWatchedValue:YES];
191        else
192                [file setResumeTimeValue:elapsed];
193        teardownPassthrough(soundState);
194}
195
196- (void)stopUITimer
197{
198        [updateTimer invalidate];
199        updateTimer = nil;
200}
201
202- (void)pressAndHoldLeftArrow
203{
204        [self setSkipTimer];
205        skipSpeed = -1;
206}
207
208- (void)pressAndHoldRightArrow
209{
210        [self setSkipTimer];
211        skipSpeed = 1;
212}
213
214- (void)setSkipTimer
215{
216        [self stopSkip];
217        skipTimer = [NSTimer scheduledTimerWithTimeInterval:SKIP_INTERVAL target:self selector:@selector(doSkip:) userInfo:nil repeats:YES];
218        [self doSkip:nil];
219}
220
221- (void)doSkip:(NSTimer *)timer
222{
223        float time = [self elapsedPlaybackTime];
224        if(skipSpeed < 0)
225        {
226                time += skipSpeed * SKIP_INTERVAL * 3;
227                skipSpeed = MAX(skipSpeed - SKIP_ACCELL, -16);
228        }
229        else
230        {
231                time += skipSpeed * SKIP_INTERVAL * 2;
232                skipSpeed = MIN(skipSpeed + SKIP_ACCELL, 16);
233        }
234        double duration = [self trackDuration];
235        if(time < 0)
236        {
237                time = 0;
238                [self stopSkip];
239        }
240        else if(time > duration)
241        {
242                time = duration;
243        }
244        [self setElapsedPlaybackTime:time];
245        [self updateUI:timer];
246}
247
248- (void)stopSkip
249{
250        skipSpeed = 0;
251        [skipTimer invalidate];
252        skipTimer = nil;
253}
254
255- (void)resume
256{
257        [self play];
258}
259
260- (void)leftArrowClick
261{
262        [movie gotoBeginning];
263        [self updateUI:nil];
264}
265
266- (void)rightArrowClick
267{
268        [movie gotoEnd];
269        [self updateUI:nil];
270}
271
272- (void)updateUI:(NSTimer *)Timer
273{
274        if([self elapsedPlaybackTime] >= [self trackDuration])
275                [self stop];
276        [[NSNotificationCenter defaultCenter] postNotificationName:@"BRMPPlaybackProgressChanged" object:self];
277        [[NSNotificationCenter defaultCenter] postNotificationName:kBRMediaPlayerPlaybackProgressChanged object:self];
278}
279
280@end
Note: See TracBrowser for help on using the repository browser.