Search code examples
iosobjective-carraysmpmovieplayercontroller

Iterate Over Array of Videos iOS


I have an array of URL extensions. The goal is piecewise:

  1. Add the extension to the base URL to create a URL to a specific video.

  2. Play video in MPMovieViewController using YTViewExtractor.

  3. Repeat for next URL extension in array when MPMovieFinishReasonPlaybackEnded = TRUE or when next button is pressed

This is my work thus far:

int i;
for (i=0; i < [_uriToBeAppended count]; i++)
{

    NSString *uriString = [_uriToBeAppended  objectAtIndex:i];
    NSString *urlString = [NSString stringWithFormat:@"http://vimeo.com/%@", uriString];

    NSLog(@"URL String: %@", urlString);

    [YTVimeoExtractor fetchVideoURLFromURL:urlString
                                   quality:YTVimeoVideoQualityMedium
                         completionHandler:^(NSURL *videoURL, NSError *error, YTVimeoVideoQuality quality) {
                             if (error) {
                                 // handle error
                                 NSLog(@"Video URL: %@", [videoURL absoluteString]);
                             } else {
                                 // run player
                                 self.moviePlayer = [[MPMoviePlayerViewController alloc] initWithContentURL:videoURL];
                                 [self.moviePlayer.moviePlayer prepareToPlay];
                                 [self presentViewController:self.moviePlayer animated:YES completion:nil];
                             }
                         }];
}

Logs:

    2014-10-11 22:30:05.528 Voulette[668:162653] URL String: http://vimeo.com/96558506
.
.
2014-10-11 22:30:05.577 Voulette[668:162653] URL String: http://vimeo.com/6615855



2014-10-11 22:30:06.997 Voulette[668:162653] -[UIApplication beginIgnoringInteractionEvents] overflow. Ignoring.
.
.
2014-10-11 22:30:09.700 Voulette[668:162653] -[UIApplication beginIgnoringInteractionEvents] overflow. Ignoring.



2014-10-11 22:30:10.063 Voulette[668:162653] -[UIApplication endIgnoringInteractionEvents] called without matching -beginIgnoringInteractionEvents. Ignoring.
.
.
2014-10-11 22:30:10.189 Voulette[668:162653] -[UIApplication endIgnoringInteractionEvents] called without matching -beginIgnoringInteractionEvents. Ignoring.



2014-10-11 22:30:11.519 Voulette[668:162653] Warning: Attempt to present <MPMoviePlayerViewController: 0x1568fcd0> on <ViewController: 0x1554e3e0> whose view is not in the window hierarchy!
.
.
2014-10-11 22:30:11.729 Voulette[668:162653] Warning: Attempt to present <MPMoviePlayerViewController: 0x16818810> on <ViewController: 0x1554e3e0> whose view is not in the window hierarchy!



2014-10-11 22:30:11.739 Voulette[668:162653] -[UIApplication beginIgnoringInteractionEvents] overflow. Ignoring.
2014-10-11 22:30:11.742 Voulette[668:162653] Warning: Attempt to present <MPMoviePlayerViewController: 0x1681d690> on <ViewController: 0x1554e3e0> whose view is not in the window hierarchy!
.
.
2014-10-11 22:30:11.887 Voulette[668:162653] -[UIApplication beginIgnoringInteractionEvents] overflow. Ignoring.
2014-10-11 22:30:11.903 Voulette[668:162653] Warning: Attempt to present <MPMoviePlayerViewController: 0x157b1e70> on <ViewController: 0x1554e3e0> whose view is not in the window hierarchy!



2014-10-11 22:30:12.674 Voulette[668:162653] -[UIApplication endIgnoringInteractionEvents] called without matching -beginIgnoringInteractionEvents. Ignoring.
.
.
2014-10-11 22:30:12.699 Voulette[668:162653] -[UIApplication endIgnoringInteractionEvents] called without matching -beginIgnoringInteractionEvents. Ignoring.

The logs indicate that the for loop goes through each action for all elements in the array before proceeding to the next action contained in the loop.

What I have is not producing the desired output and I am grateful for any feedback or advice.


Solution

  • Since the playing of a movie is an asynchronous event, your loop will execute all the way through before the first movie has barely even started (probably before actually). You need to put the code in a method that you call when the movie is done, and use a counter to keep track of which url to pick instead of using a loop.

    -(void)playNextMovie {
        static int i = 0;
        if (i < _uriToBeAppended.count) {
            NSString *uriString = [_uriToBeAppended  objectAtIndex:i];
            NSString *urlString = [NSString stringWithFormat:@"http://vimeo.com/%@", uriString];
    
            NSLog(@"URL String: %@", urlString);
    
            [YTVimeoExtractor fetchVideoURLFromURL:urlString
                                       quality:YTVimeoVideoQualityMedium
                             completionHandler:^(NSURL *videoURL, NSError *error, YTVimeoVideoQuality quality) {
                                 if (error) {
                                     // handle error
                                     NSLog(@"Video URL: %@", [videoURL absoluteString]);
                                 } else {
                                     // run player
                                     self.moviePlayer = [[MPMoviePlayerViewController alloc] initWithContentURL:videoURL];
                                     [self.moviePlayer.moviePlayer prepareToPlay];
                                     [self presentViewController:self.moviePlayer animated:YES completion:nil];
                                 }
                             }];
            i++;
        }
    
    }
    

    Call this method to start your first movie, then call it again when the MPMoviePlayerPlaybackDidFinishNotification gets called.