| 1 | /* |
|---|
| 2 | * CMPDVDPlayerController.m |
|---|
| 3 | * CommonMediaPlayer |
|---|
| 4 | * |
|---|
| 5 | * Created by Graham Booker on Feb. 3 2010 |
|---|
| 6 | * Copyright 2010 Common Media Player |
|---|
| 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 | * Lesser General Public License as published by the Free Software Foundation; either version 3 of the |
|---|
| 11 | * License, 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 Lesser |
|---|
| 15 | * General Public License for more details. |
|---|
| 16 | * |
|---|
| 17 | * You should have received a copy of the GNU Lesser General Public License along with this program; if |
|---|
| 18 | * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA |
|---|
| 19 | * 02111-1307, USA. |
|---|
| 20 | */ |
|---|
| 21 | |
|---|
| 22 | #import "CMPDVDPlayerController.h" |
|---|
| 23 | #import "CMPDVDPlayer.h" |
|---|
| 24 | #import "CMPDVDWindowCreationAction.h" |
|---|
| 25 | #import "CMPATVVersion.h" |
|---|
| 26 | #import "CoreGraphicsServices.h" |
|---|
| 27 | |
|---|
| 28 | @interface NSObject (compat) |
|---|
| 29 | - (void)setOpacity:(float)opacity; |
|---|
| 30 | @end |
|---|
| 31 | |
|---|
| 32 | @interface CMPDVDPlayerController () |
|---|
| 33 | - (void)showResumeOverlayWithDismiss:(BOOL)dismiss; |
|---|
| 34 | @end |
|---|
| 35 | |
|---|
| 36 | |
|---|
| 37 | @implementation CMPDVDPlayerController |
|---|
| 38 | |
|---|
| 39 | + (NSSet *)knownPlayers |
|---|
| 40 | { |
|---|
| 41 | return [NSSet setWithObject:[CMPDVDPlayer class]]; |
|---|
| 42 | } |
|---|
| 43 | |
|---|
| 44 | #ifdef PLAY_WITH_OVERLAY |
|---|
| 45 | static NSTimer *timer = nil; |
|---|
| 46 | #endif |
|---|
| 47 | |
|---|
| 48 | - (id)initWithScene:(BRRenderScene *)scene player:(id <CMPPlayer>)aPlayer |
|---|
| 49 | { |
|---|
| 50 | if([[BRMenuController class] instancesRespondToSelector:@selector(initWithScene:)]) |
|---|
| 51 | self = [super initWithScene:scene]; |
|---|
| 52 | else |
|---|
| 53 | self = [super init]; |
|---|
| 54 | if(!self) |
|---|
| 55 | return self; |
|---|
| 56 | |
|---|
| 57 | [[self list] setDatasource:self]; |
|---|
| 58 | |
|---|
| 59 | player = [aPlayer retain]; |
|---|
| 60 | [player setController:self]; |
|---|
| 61 | |
|---|
| 62 | [self setListTitle:@"Initiating DVD Playback"]; |
|---|
| 63 | [self setListIcon:nil]; |
|---|
| 64 | |
|---|
| 65 | windowCreation = [[CMPDVDWindowCreationAction alloc] initWithController:self andSettings:nil]; |
|---|
| 66 | #ifdef PLAY_WITH_OVERLAY |
|---|
| 67 | [timer invalidate]; |
|---|
| 68 | timer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(something) userInfo:nil repeats:NO]; |
|---|
| 69 | #endif |
|---|
| 70 | |
|---|
| 71 | return self; |
|---|
| 72 | } |
|---|
| 73 | |
|---|
| 74 | #ifdef PLAY_WITH_OVERLAY |
|---|
| 75 | - (void)setOpacity:(float)opacity |
|---|
| 76 | { |
|---|
| 77 | CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); |
|---|
| 78 | float clearComp[] = {0, 0, 0, 0}; |
|---|
| 79 | CGColorRef clear = CGColorCreate(space, clearComp); |
|---|
| 80 | id layer = [[self header] layer]; |
|---|
| 81 | int count = 0; |
|---|
| 82 | while(layer != nil) |
|---|
| 83 | { |
|---|
| 84 | // [layer setOpaque:NO]; |
|---|
| 85 | NSLog(@"Layer is %@ with %d children", layer, [[layer sublayers] count]); |
|---|
| 86 | id superlayer = [layer superlayer]; |
|---|
| 87 | // if(count < 6) |
|---|
| 88 | // [layer setOpacity:opacity]; |
|---|
| 89 | [layer setBackgroundColor:clear]; |
|---|
| 90 | NSLog(@"Set opacity of %d layer", count); |
|---|
| 91 | layer = superlayer; |
|---|
| 92 | count++; |
|---|
| 93 | } |
|---|
| 94 | } |
|---|
| 95 | |
|---|
| 96 | - (void)something |
|---|
| 97 | { |
|---|
| 98 | static int counter = 0; |
|---|
| 99 | NSString *str = @"Some really long string for testing"; |
|---|
| 100 | [self setListTitle:[str substringToIndex:counter]]; |
|---|
| 101 | // [self setOpacity:0.0f]; |
|---|
| 102 | // if(counter == 0) |
|---|
| 103 | // { |
|---|
| 104 | // CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); |
|---|
| 105 | // float clearComp[] = {0, 0, 0, 0}; |
|---|
| 106 | // CGColorRef clear = CGColorCreate(space, clearComp); |
|---|
| 107 | // id layer = [[self header] layer]; |
|---|
| 108 | // int count = 0; |
|---|
| 109 | // while(layer != nil) |
|---|
| 110 | // { |
|---|
| 111 | // [layer setOpaque:NO]; |
|---|
| 112 | // NSLog(@"Layer is %@ with %d children", layer, [[layer sublayers] count]); |
|---|
| 113 | // id superlayer = [layer superlayer]; |
|---|
| 114 | //// if(count < 6) |
|---|
| 115 | // [layer setOpacity:0.0f]; |
|---|
| 116 | // NSLog(@"Set opacity of %d layer", count); |
|---|
| 117 | // layer = superlayer; |
|---|
| 118 | // count++; |
|---|
| 119 | // } |
|---|
| 120 | // } |
|---|
| 121 | counter++; |
|---|
| 122 | if(counter < [str length]) |
|---|
| 123 | timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(something) userInfo:nil repeats:NO]; |
|---|
| 124 | else |
|---|
| 125 | { |
|---|
| 126 | timer = nil; |
|---|
| 127 | counter = 0; |
|---|
| 128 | } |
|---|
| 129 | |
|---|
| 130 | } |
|---|
| 131 | #endif |
|---|
| 132 | |
|---|
| 133 | - (void) dealloc |
|---|
| 134 | { |
|---|
| 135 | #ifdef PLAY_WITH_OVERLAY |
|---|
| 136 | [timer invalidate]; |
|---|
| 137 | timer = nil; |
|---|
| 138 | #endif |
|---|
| 139 | [player release]; |
|---|
| 140 | [delegate release]; |
|---|
| 141 | [windowCreation release]; |
|---|
| 142 | [overlayDismiss invalidate]; |
|---|
| 143 | [subtitlesOverlay release]; |
|---|
| 144 | [audioOverlay release]; |
|---|
| 145 | [chapterOverlay release]; |
|---|
| 146 | [blurredMenu release]; |
|---|
| 147 | [super dealloc]; |
|---|
| 148 | } |
|---|
| 149 | |
|---|
| 150 | |
|---|
| 151 | - (id <CMPPlayer>)player |
|---|
| 152 | { |
|---|
| 153 | return player; |
|---|
| 154 | } |
|---|
| 155 | |
|---|
| 156 | - (void)setPlaybackSettings:(NSDictionary *)settings |
|---|
| 157 | { |
|---|
| 158 | NSNumber *resume = [settings objectForKey:CMPPlayerResumeTimeKey]; |
|---|
| 159 | if(resume != nil) |
|---|
| 160 | { |
|---|
| 161 | [player setResumeTime:[resume intValue]]; |
|---|
| 162 | } |
|---|
| 163 | } |
|---|
| 164 | |
|---|
| 165 | - (void)setPlaybackDelegate:(id <CMPPlayerControllerDelegate>)aDelegate |
|---|
| 166 | { |
|---|
| 167 | delegate = [aDelegate retain]; |
|---|
| 168 | } |
|---|
| 169 | |
|---|
| 170 | - (id <CMPPlayerControllerDelegate>)delegate |
|---|
| 171 | { |
|---|
| 172 | return delegate; |
|---|
| 173 | } |
|---|
| 174 | |
|---|
| 175 | - (void)initiatePlayback |
|---|
| 176 | { |
|---|
| 177 | // [self setOpacity:0.0f]; |
|---|
| 178 | [windowCreation openWithError:nil]; |
|---|
| 179 | BOOL resume = NO; |
|---|
| 180 | CMPDVDOverlayWindow *shield = [windowCreation addBlackShieldWindow]; |
|---|
| 181 | [shield display]; |
|---|
| 182 | [player initiatePlaybackWithResume:&resume]; |
|---|
| 183 | if(resume) |
|---|
| 184 | { |
|---|
| 185 | [self showResumeOverlayWithDismiss:NO]; |
|---|
| 186 | [windowCreation performSelector:@selector(closeOverlay:) withObject:shield afterDelay:0.5]; |
|---|
| 187 | } |
|---|
| 188 | else |
|---|
| 189 | [windowCreation closeOverlay:shield]; |
|---|
| 190 | } |
|---|
| 191 | |
|---|
| 192 | - (void)playbackStopped |
|---|
| 193 | { |
|---|
| 194 | [[self stack] popController]; |
|---|
| 195 | } |
|---|
| 196 | |
|---|
| 197 | #ifdef PLAY_WITH_OVERLAY |
|---|
| 198 | - (BOOL)newFrameForTime:(void *)fp8 |
|---|
| 199 | { |
|---|
| 200 | return YES; |
|---|
| 201 | static int count = 0; |
|---|
| 202 | if(count == 0) |
|---|
| 203 | { |
|---|
| 204 | count = 0; |
|---|
| 205 | return YES; |
|---|
| 206 | } |
|---|
| 207 | // count++; |
|---|
| 208 | return NO; |
|---|
| 209 | } |
|---|
| 210 | |
|---|
| 211 | - (void)drawFrameInBounds:(struct CGSize)size |
|---|
| 212 | { |
|---|
| 213 | if(!blacked) |
|---|
| 214 | { |
|---|
| 215 | blacked = YES; |
|---|
| 216 | glColor4f(0, 0, 0, GL_ONE); |
|---|
| 217 | glBegin(GL_QUADS); |
|---|
| 218 | glVertex2f(0, 0); |
|---|
| 219 | glVertex2f(0, size.height); |
|---|
| 220 | glVertex2f(size.width, size.height); |
|---|
| 221 | glVertex2f(size.width, 0); |
|---|
| 222 | glEnd(); |
|---|
| 223 | } |
|---|
| 224 | |
|---|
| 225 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
|---|
| 226 | return; |
|---|
| 227 | |
|---|
| 228 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
|---|
| 229 | glPixelZoom( 1.0, -1.0 ); |
|---|
| 230 | CGSConnectionID cid = _CGSDefaultConnection(); |
|---|
| 231 | CGRect bounds; |
|---|
| 232 | CGSWindowID dvdWindow = [windowCreation dvdWindow]; |
|---|
| 233 | if(!dvdWindow) |
|---|
| 234 | return; |
|---|
| 235 | CGSGetWindowBounds(cid, dvdWindow, &bounds); |
|---|
| 236 | NSLog(@"Bounds is %fx%f - %fx%f", bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); |
|---|
| 237 | // CGLGetCurrentContext() |
|---|
| 238 | char *bitmap = malloc(bounds.size.width *bounds.size.height * 4); |
|---|
| 239 | CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); |
|---|
| 240 | CGContextRef context = CGBitmapContextCreate(bitmap, bounds.size.width, bounds.size.height, 8, bounds.size.width * 4, colorspace, kCGImageAlphaNoneSkipLast); |
|---|
| 241 | // Copy the contents of the window to the graphic context |
|---|
| 242 | CGContextCopyWindowCaptureContentsToRect(context, bounds, cid, dvdWindow, bounds); |
|---|
| 243 | |
|---|
| 244 | glRasterPos2f(0, 0); |
|---|
| 245 | glDrawPixels(bounds.size.width, bounds.size.height, GL_RGBA, GL_UNSIGNED_BYTE, bitmap); |
|---|
| 246 | |
|---|
| 247 | // GLuint texName; |
|---|
| 248 | // glGenTextures(1, &texName); |
|---|
| 249 | // glBindTexture (GL_TEXTURE_RECTANGLE_EXT, texName); |
|---|
| 250 | // glTexImage2D (GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, bounds.size.width, bounds.size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmap); |
|---|
| 251 | // glBindTexture (GL_TEXTURE_RECTANGLE_EXT, texName); |
|---|
| 252 | // |
|---|
| 253 | // glBegin (GL_QUADS); |
|---|
| 254 | // glTexCoord2f (0.0f, 0.0f); // draw upper left in world coordinates |
|---|
| 255 | // glVertex2f (bounds.origin.x, bounds.origin.y); |
|---|
| 256 | // |
|---|
| 257 | // glTexCoord2f (0.0f, bounds.size.height); // draw lower left in world coordinates |
|---|
| 258 | // glVertex2f (bounds.origin.x, bounds.origin.y + bounds.size.height); |
|---|
| 259 | // |
|---|
| 260 | // glTexCoord2f (bounds.size.width, bounds.size.height); // draw upper right in world coordinates |
|---|
| 261 | // glVertex2f (bounds.origin.x + bounds.size.width, bounds.origin.y + bounds.size.height); |
|---|
| 262 | // |
|---|
| 263 | // glTexCoord2f (bounds.size.width, 0.0f); // draw lower right in world coordinates |
|---|
| 264 | // glVertex2f (bounds.origin.x + bounds.size.width, bounds.origin.y); |
|---|
| 265 | // glEnd (); |
|---|
| 266 | // glDeleteTextures(1, &texName); |
|---|
| 267 | CGContextRelease(context); |
|---|
| 268 | CGColorSpaceRelease(colorspace); |
|---|
| 269 | free(bitmap); |
|---|
| 270 | } |
|---|
| 271 | |
|---|
| 272 | - (void)controlWasActivated |
|---|
| 273 | { |
|---|
| 274 | [super controlWasActivated]; |
|---|
| 275 | [[BRRenderer singleton] addPlaybackDelegate:self]; |
|---|
| 276 | } |
|---|
| 277 | #endif |
|---|
| 278 | |
|---|
| 279 | - (void)wasPushed |
|---|
| 280 | { |
|---|
| 281 | [super wasPushed]; |
|---|
| 282 | [self performSelector:@selector(initiatePlayback) withObject:nil afterDelay:0.3]; |
|---|
| 283 | } |
|---|
| 284 | |
|---|
| 285 | - (void)wasPopped |
|---|
| 286 | { |
|---|
| 287 | [super wasPopped]; |
|---|
| 288 | #ifdef PLAY_WITH_OVERLAY |
|---|
| 289 | [[BRRenderer singleton] removePlaybackDelegate:self]; |
|---|
| 290 | |
|---|
| 291 | // id layer = [[self header] layer]; |
|---|
| 292 | // int count = 0; |
|---|
| 293 | // while(layer != nil) |
|---|
| 294 | // { |
|---|
| 295 | // [layer setOpaque:YES]; |
|---|
| 296 | // NSLog(@"Layer is %@ with %d children", layer, [[layer sublayers] count]); |
|---|
| 297 | // id superlayer = [layer superlayer]; |
|---|
| 298 | // [layer setOpacity:1.0f]; |
|---|
| 299 | // NSLog(@"Set opacity of %d layer", count); |
|---|
| 300 | // layer = superlayer; |
|---|
| 301 | // count++; |
|---|
| 302 | // } |
|---|
| 303 | |
|---|
| 304 | #endif |
|---|
| 305 | NSMutableDictionary *endSettings = [[NSMutableDictionary alloc] init]; |
|---|
| 306 | double elapsed = [player elapsedPlaybackTime]; |
|---|
| 307 | double duration = [player trackDuration]; |
|---|
| 308 | |
|---|
| 309 | if(elapsed != 0.0) |
|---|
| 310 | [endSettings setObject:[NSNumber numberWithDouble:elapsed] forKey:CMPPlayerResumeTimeKey]; |
|---|
| 311 | if(duration != 0.0) |
|---|
| 312 | [endSettings setObject:[NSNumber numberWithDouble:duration] forKey:CMPPlayerDurationTimeKey]; |
|---|
| 313 | [delegate controller:self didEndWithSettings:endSettings]; |
|---|
| 314 | [delegate autorelease]; |
|---|
| 315 | delegate = nil; |
|---|
| 316 | [endSettings release]; |
|---|
| 317 | |
|---|
| 318 | [player stopPlayback]; |
|---|
| 319 | [windowCreation closeWithError:nil]; |
|---|
| 320 | } |
|---|
| 321 | |
|---|
| 322 | - (void)releaseAllOverlaysWithFadeTime:(float)fadeTime |
|---|
| 323 | { |
|---|
| 324 | [windowCreation closeAllOverlaysWithFadeTime:fadeTime]; |
|---|
| 325 | [subtitlesOverlay release]; |
|---|
| 326 | subtitlesOverlay = nil; |
|---|
| 327 | [audioOverlay release]; |
|---|
| 328 | audioOverlay = nil; |
|---|
| 329 | [chapterOverlay release]; |
|---|
| 330 | chapterOverlay = nil; |
|---|
| 331 | overlayMode = CMPDVDPlayerControllerOverlayModeNormal; |
|---|
| 332 | } |
|---|
| 333 | |
|---|
| 334 | - (void)dismissOverlaysWithFadeTime:(float)fadeTime |
|---|
| 335 | { |
|---|
| 336 | [self releaseAllOverlaysWithFadeTime:fadeTime]; |
|---|
| 337 | [overlayDismiss invalidate]; |
|---|
| 338 | overlayDismiss = nil; |
|---|
| 339 | } |
|---|
| 340 | |
|---|
| 341 | - (void)fadeOverlays |
|---|
| 342 | { |
|---|
| 343 | [self dismissOverlaysWithFadeTime:0.5]; |
|---|
| 344 | } |
|---|
| 345 | |
|---|
| 346 | - (void)resetOverlayTimerTo:(NSTimeInterval)time |
|---|
| 347 | { |
|---|
| 348 | [overlayDismiss invalidate]; |
|---|
| 349 | overlayDismiss = [NSTimer scheduledTimerWithTimeInterval:time target:self selector:@selector(fadeOverlays) userInfo:nil repeats:NO]; |
|---|
| 350 | } |
|---|
| 351 | |
|---|
| 352 | - (void)showPlayheadOverlay |
|---|
| 353 | { |
|---|
| 354 | CMPDVDPlayerPlayHead *playhead = [windowCreation addPlayheadOverlay]; |
|---|
| 355 | [playhead setPlayer:player]; |
|---|
| 356 | [playhead displayWithFadeTime:0.1]; |
|---|
| 357 | } |
|---|
| 358 | |
|---|
| 359 | - (void)showSubAndAudioOverlays |
|---|
| 360 | { |
|---|
| 361 | [self releaseAllOverlaysWithFadeTime:0]; |
|---|
| 362 | |
|---|
| 363 | subtitlesOverlay = [[windowCreation addTextOverlayInPosition:CMPDVDOverlayUpperLeft] retain]; |
|---|
| 364 | [subtitlesOverlay setText:[player currentSubFormat]]; |
|---|
| 365 | [subtitlesOverlay displayWithFadeTime:0.25]; |
|---|
| 366 | audioOverlay = [[windowCreation addTextOverlayInPosition:CMPDVDOverlayUpperRight] retain]; |
|---|
| 367 | [audioOverlay setText:[player currentAudioFormat]]; |
|---|
| 368 | [audioOverlay displayWithFadeTime:0.25]; |
|---|
| 369 | overlayMode = CMPDVDPlayerControllerOverlayModeSubAndAudio; |
|---|
| 370 | [self resetOverlayTimerTo:10]; |
|---|
| 371 | } |
|---|
| 372 | |
|---|
| 373 | - (void)showChapterOverlay |
|---|
| 374 | { |
|---|
| 375 | [self releaseAllOverlaysWithFadeTime:0]; |
|---|
| 376 | chapterOverlay = [[windowCreation addTextOverlayInPosition:CMPDVDOverlayUpperLeft] retain]; |
|---|
| 377 | [chapterOverlay setText:[NSString stringWithFormat:@"Chapter %d/%d", [player currentChapter], [player chapters]]]; |
|---|
| 378 | [chapterOverlay displayWithFadeTime:0.25]; |
|---|
| 379 | [self showPlayheadOverlay]; |
|---|
| 380 | overlayMode = CMPDVDPlayerControllerOverlayModeChapters; |
|---|
| 381 | [self resetOverlayTimerTo:10]; |
|---|
| 382 | } |
|---|
| 383 | |
|---|
| 384 | - (void)setOverlayText:(NSString *)text inPosition:(CMPDVDOverlayPosition)position dismissingOthers:(BOOL)dismiss |
|---|
| 385 | { |
|---|
| 386 | if(overlayMode != CMPDVDPlayerControllerOverlayModeNormal) |
|---|
| 387 | return; |
|---|
| 388 | if(dismiss) |
|---|
| 389 | [self releaseAllOverlaysWithFadeTime:0]; |
|---|
| 390 | CMPDVDTextView *overlay = [windowCreation addTextOverlayInPosition:position]; |
|---|
| 391 | [overlay setText:text]; |
|---|
| 392 | [overlay displayWithFadeTime:0.25]; |
|---|
| 393 | [self resetOverlayTimerTo:3]; |
|---|
| 394 | } |
|---|
| 395 | |
|---|
| 396 | - (void)showResumeOverlayWithDismiss:(BOOL)dismiss |
|---|
| 397 | { |
|---|
| 398 | if(dismiss) |
|---|
| 399 | [self dismissOverlaysWithFadeTime:0]; |
|---|
| 400 | blurredMenu = [[windowCreation addBlurredMenuOverlayWithItems:[NSArray arrayWithObjects:@"Resume Playback", @"Start From Beginning", @"Main Menu", nil]] retain]; |
|---|
| 401 | [blurredMenu displayWithFadeTime:0.5]; |
|---|
| 402 | } |
|---|
| 403 | |
|---|
| 404 | - (NSString *)stringForPlayerState |
|---|
| 405 | { |
|---|
| 406 | CMPDVDState state = [player state]; |
|---|
| 407 | int speed = [player playSpeed]; |
|---|
| 408 | NSString *text = nil; |
|---|
| 409 | if(state == CMPDVDStatePlaying) |
|---|
| 410 | text = [NSString stringWithFormat:@"%C", 0x25B6]; |
|---|
| 411 | if(state == CMPDVDStatePaused) |
|---|
| 412 | text = [NSString stringWithFormat:@"%C%C", 0x258C, 0x258C]; |
|---|
| 413 | else if(state == CMPDVDStateScanningForward) |
|---|
| 414 | text = [NSString stringWithFormat:@"%C%C%dx", 0x25B6, 0x25B6, speed]; |
|---|
| 415 | else if(state == CMPDVDStateScanningBackward) |
|---|
| 416 | text = [NSString stringWithFormat:@"%C%C%dx", 0x25C0, 0x25C0, speed]; |
|---|
| 417 | else if(state == CMPDVDStatePlayingSlowForward) |
|---|
| 418 | text = [NSString stringWithFormat:@"%C1/%dx", 0x25B6, speed]; |
|---|
| 419 | else if(state == CMPDVDStatePlayingSlowBackward) |
|---|
| 420 | text = [NSString stringWithFormat:@"%C1/%dx", 0x25C0, speed]; |
|---|
| 421 | |
|---|
| 422 | return text; |
|---|
| 423 | } |
|---|
| 424 | |
|---|
| 425 | - (void)showStateOverlay |
|---|
| 426 | { |
|---|
| 427 | [self setOverlayText:[self stringForPlayerState] inPosition:CMPDVDOverlayUpperLeft dismissingOthers:YES]; |
|---|
| 428 | [self showPlayheadOverlay]; |
|---|
| 429 | } |
|---|
| 430 | |
|---|
| 431 | - (BOOL)brEventAction:(BREvent *)event |
|---|
| 432 | { |
|---|
| 433 | NSLog(@"Got event %@", event); |
|---|
| 434 | BREventRemoteAction action = [CMPATVVersion remoteActionForEvent:event]; |
|---|
| 435 | if(![player playing]) |
|---|
| 436 | return [super brEventAction:event]; |
|---|
| 437 | |
|---|
| 438 | if([event value] == 0 && action != kBREventRemoteActionMenu) |
|---|
| 439 | return NO; |
|---|
| 440 | |
|---|
| 441 | BOOL inMenu = [player inMenu]; |
|---|
| 442 | CMPDVDState state = [player state]; |
|---|
| 443 | NSLog(@"State is %d and doing %d", state, action); |
|---|
| 444 | BOOL playingInSomeForm = (state == CMPDVDStatePlaying || state == CMPDVDStateScanningForward || state == CMPDVDStateScanningBackward || state == CMPDVDStatePlayingSlowForward || state == CMPDVDStatePlayingSlowBackward); |
|---|
| 445 | BOOL supressStateDisplay = NO; |
|---|
| 446 | |
|---|
| 447 | switch (action) { |
|---|
| 448 | case kBREventRemoteActionSwipeRight: |
|---|
| 449 | case kBREventRemoteActionRight: |
|---|
| 450 | if(blurredMenu) |
|---|
| 451 | return NO; |
|---|
| 452 | else if(inMenu) |
|---|
| 453 | [player doUserNavigation:CMPDVDPlayerNavigationRight]; |
|---|
| 454 | else if(overlayMode == CMPDVDPlayerControllerOverlayModeSubAndAudio) |
|---|
| 455 | { |
|---|
| 456 | [player nextAudioStream]; |
|---|
| 457 | [audioOverlay setText:[player currentAudioFormat]]; |
|---|
| 458 | [self resetOverlayTimerTo:10]; |
|---|
| 459 | } |
|---|
| 460 | else if(overlayMode == CMPDVDPlayerControllerOverlayModeChapters) |
|---|
| 461 | { |
|---|
| 462 | [player nextChapter]; |
|---|
| 463 | [chapterOverlay setText:[NSString stringWithFormat:@"Chapter %d/%d", [player currentChapter], [player chapters]]]; |
|---|
| 464 | [self resetOverlayTimerTo:10]; |
|---|
| 465 | } |
|---|
| 466 | else if(playingInSomeForm) |
|---|
| 467 | [player incrementScanRate]; |
|---|
| 468 | else |
|---|
| 469 | [player nextFrame]; |
|---|
| 470 | break; |
|---|
| 471 | case kBREventRemoteActionSwipeLeft: |
|---|
| 472 | case kBREventRemoteActionLeft: |
|---|
| 473 | if(blurredMenu) |
|---|
| 474 | return NO; |
|---|
| 475 | else if(inMenu) |
|---|
| 476 | [player doUserNavigation:CMPDVDPlayerNavigationLeft]; |
|---|
| 477 | else if(overlayMode == CMPDVDPlayerControllerOverlayModeSubAndAudio) |
|---|
| 478 | { |
|---|
| 479 | [player nextSubStream]; |
|---|
| 480 | [subtitlesOverlay setText:[player currentSubFormat]]; |
|---|
| 481 | [self resetOverlayTimerTo:10]; |
|---|
| 482 | } |
|---|
| 483 | else if(overlayMode == CMPDVDPlayerControllerOverlayModeChapters) |
|---|
| 484 | { |
|---|
| 485 | [player previousChapter]; |
|---|
| 486 | [chapterOverlay setText:[NSString stringWithFormat:@"Chapter %d/%d", [player currentChapter], [player chapters]]]; |
|---|
| 487 | [self resetOverlayTimerTo:10]; |
|---|
| 488 | } |
|---|
| 489 | else if(playingInSomeForm) |
|---|
| 490 | [player decrementScanRate]; |
|---|
| 491 | else |
|---|
| 492 | //We cannot step frame backwards!!!! |
|---|
| 493 | [player decrementScanRate]; |
|---|
| 494 | break; |
|---|
| 495 | case kBREventRemoteActionSwipeUp: |
|---|
| 496 | case kBREventRemoteActionUp: |
|---|
| 497 | if(blurredMenu) |
|---|
| 498 | return [blurredMenu previousItem]; |
|---|
| 499 | else if(inMenu) |
|---|
| 500 | [player doUserNavigation:CMPDVDPlayerNavigationUp]; |
|---|
| 501 | else if(overlayMode == CMPDVDPlayerControllerOverlayModeNormal) |
|---|
| 502 | [self showSubAndAudioOverlays]; |
|---|
| 503 | else if(overlayMode == CMPDVDPlayerControllerOverlayModeSubAndAudio) |
|---|
| 504 | overlayMode = CMPDVDPlayerControllerOverlayModeNormal; |
|---|
| 505 | else if(overlayMode == CMPDVDPlayerControllerOverlayModeChapters) |
|---|
| 506 | overlayMode = CMPDVDPlayerControllerOverlayModeNormal; |
|---|
| 507 | else |
|---|
| 508 | ;//Something else |
|---|
| 509 | break; |
|---|
| 510 | case kBREventRemoteActionSwipeDown: |
|---|
| 511 | case kBREventRemoteActionDown: |
|---|
| 512 | if(blurredMenu) |
|---|
| 513 | return [blurredMenu nextItem]; |
|---|
| 514 | else if(inMenu) |
|---|
| 515 | [player doUserNavigation:CMPDVDPlayerNavigationDown]; |
|---|
| 516 | else if(overlayMode == CMPDVDPlayerControllerOverlayModeNormal) |
|---|
| 517 | [self showChapterOverlay]; |
|---|
| 518 | else if(overlayMode == CMPDVDPlayerControllerOverlayModeSubAndAudio) |
|---|
| 519 | overlayMode = CMPDVDPlayerControllerOverlayModeNormal; |
|---|
| 520 | else if(overlayMode == CMPDVDPlayerControllerOverlayModeChapters) |
|---|
| 521 | overlayMode = CMPDVDPlayerControllerOverlayModeNormal; |
|---|
| 522 | else |
|---|
| 523 | ;//Something else |
|---|
| 524 | break; |
|---|
| 525 | case kBREventRemoteActionMenu: |
|---|
| 526 | if(blurredMenu != nil) |
|---|
| 527 | return [super brEventAction:event]; |
|---|
| 528 | |
|---|
| 529 | [player pause]; |
|---|
| 530 | [self showResumeOverlayWithDismiss:YES]; |
|---|
| 531 | supressStateDisplay = YES; |
|---|
| 532 | break; |
|---|
| 533 | case kBREventRemoteActionPlay: |
|---|
| 534 | if(blurredMenu) |
|---|
| 535 | { |
|---|
| 536 | int selection = [blurredMenu selectedItem]; |
|---|
| 537 | [self dismissOverlaysWithFadeTime:0]; |
|---|
| 538 | [blurredMenu release]; |
|---|
| 539 | blurredMenu = nil; |
|---|
| 540 | switch (selection) { |
|---|
| 541 | case 0: |
|---|
| 542 | [player play]; |
|---|
| 543 | break; |
|---|
| 544 | case 1: |
|---|
| 545 | //Need to restart the playback somehow |
|---|
| 546 | [player restart]; |
|---|
| 547 | break; |
|---|
| 548 | case 2: |
|---|
| 549 | [player goToMenu]; |
|---|
| 550 | break; |
|---|
| 551 | default: |
|---|
| 552 | break; |
|---|
| 553 | } |
|---|
| 554 | supressStateDisplay = YES; |
|---|
| 555 | } |
|---|
| 556 | else if(inMenu) |
|---|
| 557 | [player doUserNavigation:CMPDVDPlayerNavigationEnter]; |
|---|
| 558 | else if(state == CMPDVDStatePlaying) |
|---|
| 559 | [player pause]; |
|---|
| 560 | else if(playingInSomeForm || state == CMPDVDStatePaused) |
|---|
| 561 | [player play]; |
|---|
| 562 | else |
|---|
| 563 | [player pause]; |
|---|
| 564 | break; |
|---|
| 565 | default: |
|---|
| 566 | NSLog(@"unknown %d", action); |
|---|
| 567 | return [super brEventAction:event]; |
|---|
| 568 | } |
|---|
| 569 | |
|---|
| 570 | if (inMenu) |
|---|
| 571 | supressStateDisplay = YES; |
|---|
| 572 | else { |
|---|
| 573 | supressStateDisplay = NO; |
|---|
| 574 | } |
|---|
| 575 | |
|---|
| 576 | |
|---|
| 577 | if(!supressStateDisplay && overlayMode == CMPDVDPlayerControllerOverlayModeNormal) |
|---|
| 578 | [self showStateOverlay]; |
|---|
| 579 | |
|---|
| 580 | return YES; |
|---|
| 581 | } |
|---|
| 582 | |
|---|
| 583 | - (NSString *)titleForRow:(long)row { |
|---|
| 584 | return nil; |
|---|
| 585 | } |
|---|
| 586 | |
|---|
| 587 | -(float)heightForRow:(long)row { |
|---|
| 588 | return 0.0f; |
|---|
| 589 | } |
|---|
| 590 | |
|---|
| 591 | -(id)itemForRow:(long)row { |
|---|
| 592 | return nil; |
|---|
| 593 | } |
|---|
| 594 | |
|---|
| 595 | - (long)itemCount { |
|---|
| 596 | return 0; |
|---|
| 597 | } |
|---|
| 598 | |
|---|
| 599 | - (void)itemSelected:(long)row |
|---|
| 600 | { |
|---|
| 601 | } |
|---|
| 602 | |
|---|
| 603 | - (id<BRMediaPreviewController>)previewControllerForItem:(long)row |
|---|
| 604 | { |
|---|
| 605 | return nil; |
|---|
| 606 | } |
|---|
| 607 | |
|---|
| 608 | - (id<BRMediaPreviewController>)previewControlForItem:(long)row |
|---|
| 609 | { |
|---|
| 610 | return [self previewControllerForItem:row]; |
|---|
| 611 | } |
|---|
| 612 | |
|---|
| 613 | @end |
|---|