MP4PlayerController.m
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:7k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. #import "MP4PlayerController.h"
  2. #import <Foundation/NSTimer.h>
  3. /*
  4.  * Objective-C++ controller object to interface with the mpeg4ip CPlayerSession model object.
  5.  *
  6.  * We have to wrap the C++ CPlayerSession object in a set of C-callable functions
  7.  * (see player_session_wrap.h) because Objective-C++ is nowhere to be found these
  8.  * days.  It would be much cooler if we could just use it directly.
  9.  */
  10.  
  11. @implementation MP4PlayerController
  12. - (id)init
  13. {
  14.     self = [super init];
  15.     player = 0;
  16.     state = CLOSED;
  17. // XXX: This stuff doesn't actually work.  I need to initialize my stuff after
  18. // de-archiving, but in some other method... what's it called?
  19.     return self;
  20. }
  21. - (void)stateHasChanged
  22. {
  23.     if (state == CLOSED) {
  24.         [volume setEnabled:NO];
  25.         [time setEnabled:NO];
  26.         [playButton setEnabled:NO];
  27.         [pauseButton setEnabled:NO];
  28.         [stopButton setEnabled:NO];
  29.         [firstLine setObjectValue:@"mpeg4ip"];
  30.         [secondLine setObjectValue:@"version 0.7"];
  31.     }
  32.     else {
  33.         [firstLine setObjectValue:filename];
  34.         [volume setEnabled:YES];
  35.         [time setEnabled:YES];
  36.         if ((CPS_get_session_state(player) != SESSION_BUFFERING) && (!needToSeek))
  37.             [time setDoubleValue:CPS_get_playing_time(player)];
  38.         [time setMaxValue:CPS_get_max_time(player)];
  39.         switch (state) {
  40.             case PLAYING:
  41.                 [secondLine setObjectValue:@"Playing"];
  42.                 [playButton setEnabled:NO];
  43.                 [pauseButton setEnabled:YES];
  44.                 [stopButton setEnabled:YES];
  45.                 break;
  46.             default:
  47.                 [playButton setEnabled:YES];
  48.                 [pauseButton setEnabled:NO];
  49. if ([time doubleValue] == 0.0) {
  50. [stopButton setEnabled:NO];
  51. [secondLine setObjectValue:@"Stopped"];
  52. }
  53. else {
  54. [stopButton setEnabled:YES];
  55. [secondLine setObjectValue:@"Paused"];
  56. }
  57. break;
  58.         }
  59.     }
  60. }
  61. - (IBAction)adjustVolume:(id)sender
  62. {
  63.     float x = [volume floatValue];
  64.     
  65.     if (player)
  66.         CPS_set_audio_volume(player, x);
  67. }
  68. - (IBAction)seek:(id)sender
  69. {
  70.     NSLog(@"seek: %f", [time doubleValue]);
  71.     
  72.     if (state == PLAYING) {
  73.         assert(player != nil);
  74.         CPS_pause_all_media(player);
  75.         CPS_play_all_media(player, ([time doubleValue] == 0.0),
  76.                             [time doubleValue]);
  77.     }
  78.     else {
  79.         needToSeek = YES;
  80.     }
  81.     [self stateHasChanged];
  82. }
  83. - (IBAction)open:(id)sender
  84. {
  85.     int result;
  86.     NSArray *fileTypes;
  87.     NSOpenPanel *oPanel;
  88.     // Close first if already open
  89.     if (player != 0) {
  90.         [self close:sender];
  91.     }
  92.     
  93.     // Ask user what to open
  94.     NSLog(@"getting file name . . .");
  95.     fileTypes = [NSArray arrayWithObject:@"td"];
  96.     oPanel = [NSOpenPanel openPanel];
  97.     result = [oPanel runModalForDirectory:nil file:nil types:nil];
  98.     if (result != NSOKButton)
  99.         return;
  100.     filename = [oPanel filename];
  101. [self doOpen];
  102. }
  103. - (IBAction)openURL:(id)sender
  104. {
  105. [[openURLPanel windowController] showWindow:sender];
  106. }
  107. - (IBAction)doOpenURL:(id)sender
  108. {
  109. [[openURLPanel windowController] close];
  110. filename = [urlComboBox objectValue];
  111. (void) [urlComboBox removeItemWithObjectValue:filename];
  112. [urlComboBox insertItemWithObjectValue:filename atIndex:0];
  113. [self doOpen];
  114. }
  115. - (void)doOpen
  116. {
  117.     int result;
  118.     char* errmsg;
  119.     if (!master_queue)
  120.         master_queue = new_CMQ();
  121.     if (!master_sem)
  122.         master_sem = SDL_CreateSemaphore(0);
  123.         
  124.     player = new_CPS(master_queue, master_sem, "MPEG-4 Player");
  125.     result = parse_name_for_c_session(player, [filename lossyCString], &errmsg);
  126.     if (result < 0) {
  127. NSString* errstr = [NSString stringWithCString:errmsg];
  128.         NSLog(@"Name parse failed: %s", errmsg);
  129.         CPS_destroy(player);
  130.         NSRunAlertPanel(@"Cannot open file", errstr, nil, nil, nil);
  131.         return;
  132.     }
  133.     
  134.     /* Cool beans, we have a file open. */
  135.     /* FIXME: Get screen location from this window somehow. */
  136.     CPS_set_screen_location(player, 100, 100);
  137.     CPS_set_screen_size(player, screenSize, 0);
  138.     
  139.     [time setMaxValue:CPS_get_max_time(player)];
  140.     [time setDoubleValue:0];
  141.     
  142.     [self adjustVolume:nil];
  143.     
  144.     if (CPS_session_is_seekable(player))
  145.         [time setEnabled:YES];
  146.     else
  147.         [time setEnabled:NO];
  148.     
  149.     state = NOT_PLAYING;
  150.     syncThreadStarted = NO;
  151.     
  152.     [self stateHasChanged];
  153. }
  154. - (IBAction)pause:(id)sender
  155. {
  156.     session_state_t pst;
  157.     assert(state == PLAYING);
  158.     assert(player != nil);
  159.     pst = CPS_get_session_state(player);
  160.     if (CPS_get_session_state(player) == SESSION_DONE) {
  161.         // Nobody else noticed this yet.
  162.         state = NOT_PLAYING;
  163.         return;
  164.     }
  165.     assert(pst != SESSION_PAUSED);
  166.     CPS_pause_all_media(player);
  167.     state = NOT_PLAYING;
  168.     [self stateHasChanged];
  169. }
  170. - (IBAction)play:(id)sender
  171. {
  172.     session_state_t pst;
  173.     double newtime;
  174. static BOOL timerStarted = NO;
  175.     assert(player != nil);
  176.     assert(state == NOT_PLAYING);
  177. if (!timerStarted) {
  178. [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(stateHasChanged) userInfo:nil repeats:YES];
  179. timerStarted = YES;
  180. }
  181.     pst = CPS_get_session_state(player);
  182.     assert(pst == SESSION_PAUSED || pst == SESSION_DONE);
  183.     if (!syncThreadStarted) {
  184.         NSLog(@"setting up sync thread . . .");
  185.         CPS_set_up_sync_thread(player);
  186.         syncThreadStarted = YES;
  187.     }
  188.     if (needToSeek) {
  189.         NSLog(@"Need to seek");
  190.         newtime = [time doubleValue];
  191.         needToSeek = NO;
  192.     }
  193.     else {
  194.         NSLog(@"Don't need to seek");
  195.         newtime = CPS_get_playing_time(player);
  196.     }
  197.     CPS_play_all_media(player, (newtime == 0.0), newtime);
  198.     state = PLAYING;
  199.     [self stateHasChanged];
  200. }
  201. - (IBAction)stop:(id)sender
  202. {
  203.     [time setDoubleValue:0];
  204.     needToSeek = YES;
  205.     if (CPS_get_session_state(player) == SESSION_DONE)
  206.         state = NOT_PLAYING;
  207.     if (state == PLAYING)
  208.         [self pause:sender];
  209.     else
  210.         [self stateHasChanged];
  211. }
  212. - (IBAction)close:(id)sender
  213. {
  214.     SDL_Event event;
  215.     NSLog(@"Destroying player . . .");
  216.     event.type = SDL_QUIT;
  217.     SDL_PushEvent(&event);
  218.     CPS_destroy(player);
  219.     player = 0;
  220.     filename = nil;
  221.     state = CLOSED;
  222.     syncThreadStarted = NO;
  223.     [self stateHasChanged];
  224.     return;
  225. }
  226. - (IBAction)setVideoSize:(id)sender
  227. {
  228.     BOOL setFullScreen = NO;
  229.     
  230.     switch ([sender indexOfSelectedItem]) {
  231.         case 0: screenSize = 1; break;
  232.         case 1: case -1: screenSize = 2; break;
  233.         case 2: screenSize = 4; break;
  234.         case 3: setFullScreen = YES; break;
  235.     }
  236.     
  237.     NSLog(@"set video size... %d", screenSize);
  238.     
  239.     if (player)
  240.         CPS_set_screen_size(player, screenSize, setFullScreen);
  241.     /* if ((!player) && setFullScreen) do something useful */
  242. }
  243. - (IBAction)setLooping:(id)sender
  244. {
  245. if ([sender state] == NSOnState) {
  246. NSRunAlertPanel(@"Error", @"Looping is not yet implemented", nil, nil, nil);
  247. [sender setState:NSOffState];
  248. }
  249.     return;
  250. }
  251. @end