2015-01-07 25 views
9

Tôi có một lớp AVPlayer được thiết lập để phát trực tuyến tệp âm thanh. Đó là một chút dài, vì vậy tôi không thể đăng toàn bộ điều ở đây. Những gì tôi đang mắc kẹt là làm thế nào để cho phép người dùng phát lại các tập tin âm thanh sau khi họ đã hoàn thành nghe nó một lần. Khi kết thúc lần đầu tiên, tôi nhận được thông báo AVPlayerItemDidPlayToEndTimeNotification chính xác. Khi tôi phát lại nó, tôi ngay lập tức nhận được thông báo tương tự, điều này ngăn tôi phát lại nó.Phát lại AVPlayerItem/AVPlayer mà không cần tải xuống lại

Làm cách nào để đặt lại cài đặt này sao cho số AVPlayerItem không nghĩ rằng nó đã phát tệp âm thanh? Tôi có thể deallocate tất cả mọi thứ và thiết lập nó một lần nữa, nhưng tôi tin rằng sẽ buộc người dùng để tải về các tập tin âm thanh một lần nữa, đó là vô nghĩa và chậm.

Dưới đây là một số phần của lớp mà tôi nghĩ là có liên quan. Đầu ra mà tôi nhận được khi cố gắng phát lại tệp trông như thế này. Hai dòng đầu tiên là chính xác những gì tôi mong đợi, nhưng thứ ba là một bất ngờ.

đang chơi
không hẹn giờ
máy nghe nhạc âm thanh phát xong âm thanh

- (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; 
} 
+0

Mọi tiến trình về điều này? Tôi đang đối mặt với một vấn đề tương tự (với một video mặc dù) Sau khi AVPlayerItemDidPlayToEndTimeNotification đi qua bạn không thể phát lại mục. Cách giải quyết hiện tại của tôi là tạo một Item + Player mới nhưng điều này chỉ cần tải xuống toàn bộ điều – eyeballz

+0

@eyeballz - Không. Hiện tại, tôi đang giải quyết nó và sau đó khôi phục lại. Thật là một giải pháp tốt, nhưng đó là giải pháp tốt nhất mà tôi có thể làm ngay bây giờ. Nếu bạn tìm ra thứ gì đó, hãy đăng bài. – Alex

+0

Ok tôi nhận được nó làm việc cho tôi, nhưng Video của nó không âm thanh. Các vấn đề với video dường như là bạn phải giữ PlayerLayer là tốt, nhưng bạn không có một lớp của loại đó bất cứ nơi nào cho âm thanh. – eyeballz

Trả lời

10

Bạn có thể gọi phương thức seekToTime khi nghe nhạc của bạn nhận được AVPlayerItemDidPlayToEndTimeNotification

func itemDidFinishPlaying() { 
    self.player.seekToTime(kCMTimeZero) 
    self.player.play() 
} 
-1

tôi đề nghị sử dụng AVQueueplayer. Điều này được phát biểu vào lúc 15:00 trong video tại đây: https://developer.apple.com/videos/play/wwdc2016/503/

Đây là tùy chọn tốt nhất để phát lại bản địa và được thảo luận tại sao.

+1

"Apple nói XYZ là tốt nhất cho bản địa" là một câu trả lời khá tối thiểu. Vui lòng tóm tắt các đối số của video được liên kết ở đây là tốt nhất bạn có thể. –

Các vấn đề liên quan