14

オーディオ ファイルをストリーミングする AVPlayer クラスをすべてセットアップしました。少し長いので、ここにすべてを掲載することはできません。私が立ち往生しているのは、ユーザーがオーディオファイルを一度聞き終わった後にオーディオファイルを再生できるようにする方法です。初めて終了すると、通知が正しく届きますAVPlayerItemDidPlayToEndTimeNotification。再生しようとすると、すぐに同じ通知を受け取り、再生がブロックされます。

AVPlayerItemオーディオ ファイルが既に再生されていると が認識しないように、これをリセットするにはどうすればよいですか? すべての割り当てを解除して再度設定することもできますが、それではユーザーがオーディオ ファイルを再度ダウンロードする必要があり、これは無意味で時間がかかります。

私が関連していると思われるクラスのいくつかの部分を以下に示します。ファイルを再生しようとすると、次のような出力が得られます。最初の 2 行はまさに私が期待するものですが、3 行目は驚きです。

再生中
タイマーなし
オーディオ プレーヤー オーディオの再生が終了しました

- (id) initWithURL : (NSString *) urlString
{
    self = [super init];
    if (self) {
        self.isPlaying = NO;
        self.verbose = YES;

        if (self.verbose) NSLog(@"url: %@", urlString);
        NSURL *url = [NSURL URLWithString:urlString];

        self.playerItem = [AVPlayerItem playerItemWithURL:url];
        self.player = [[AVPlayer alloc] initWithPlayerItem:self.playerItem];

        [self determineAudioPlayTime : self.playerItem];

        self.lengthOfAudioInSeconds = @0.0f;

        [self.player addObserver:self forKeyPath:@"status" options:0 context:nil];

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.playerItem];
    }

    return self;
}

// this is what gets called when the user clicks the play button after they have 
// listened to the file and the AVPlayerItemDidPlayToEndTimeNotification has been received
- (void) playAgain {
    [self.playerItem seekToTime:kCMTimeZero];
    [self toggleState];
}

- (void) toggleState {
    self.isPlaying = !self.isPlaying;

    if (self.isPlaying) {
        if (self.verbose) NSLog(@"is playing");
        [self.player play];

        if (!timer) {
            NSLog(@"no timer");
            CMTime audioTimer = CMTimeMake(0, 1);
            [self.player seekToTime:audioTimer];

            timer = [NSTimer scheduledTimerWithTimeInterval:1.0
                                                     target:self
                                                   selector:@selector(updateProgress)
                                                   userInfo:nil
                                                    repeats:YES];
        }

    } else {
        if (self.verbose) NSLog(@"paused");
        [self.player pause];
    }
}

-(void)itemDidFinishPlaying:(NSNotification *) notification {
    if (self.verbose) NSLog(@"audio player has finished playing audio");
    [[NSNotificationCenter defaultCenter] postNotificationName:@"audioFinished" object:self];
    [timer invalidate];
    timer = nil;
    self.totalSecondsPlayed = [NSNumber numberWithInt:0];
    self.isPlaying = NO;
}
4

2 に答える 2