停止播放 AVPlayer 项目并替换为新的

Stop Playback of AVPlayer item and replace with new

我的应用程序有一个表视图,当 selected 时,它会打开一个新的视图控制器并使用 AVPlayer 开始播放传递给它的 URL。但是,当他们返回 select 播放新项目时,我无法让它停止第一个,然后开始播放第二个。有什么建议吗?

- (void)viewWillAppear:(BOOL)animated {
        [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

          
           [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
           [self becomeFirstResponder];
           NSURL *newURL = [NSURL URLWithString:_entry.articleUrl];
          
           AVPlayer *player = [AVPlayer playerWithURL:newURL];
    
            _controller = [[AVPlayerViewController alloc]init];
            _controller.player = player;
        
            
           
            // show the view controller
            [self addChildViewController:_controller];
            [self.view addSubview:_controller.view];
            _controller.view.frame = self.view.frame;
    [player play];
   
    self.title = _entry.articleTitle;
   
    

    [super viewWillAppear:YES];
}

EDIT 我已经将其更改为 return 当您向 startPlaying 发送消息时播放器 - 这样更新您的控制器真的很容易,正如所讨论的在评论中。

这是一个可能有用的大纲 - 没有测试它,但希望它能解决你的问题。

头文件应该包含

@interface MyPlayer : NSObject

// Start playing some URL and return the player
+ ( AVPlayer * ) startPlaying:( NSURL * ) url;

@end

并且在 m 文件中,与之前非常相似,

#import <AVKit/AVKit.h>
#import "MyPlayer.h"

@interface MyPlayer ()

@property (nonatomic,strong) NSObject * playerLock;
@property (nonatomic,strong) AVPlayer * player;

@end

@implementation MyPlayer

// Initialise
- ( id ) init
{
    self = super.init;

    if ( self )
    {
        self.playerLock = NSObject.new;
    }

    return self;
}

// Return singleton
+ ( MyPlayer * ) myPlayer
{
    static MyPlayer * mp;
    static dispatch_once_t t;

    dispatch_once ( & t, ^ {

        mp = [[MyPlayer alloc] init];

    } );

    return mp;
}

// Start playing some URL and return the player
+ ( AVPlayer * ) startPlaying:( NSURL * ) url
{
    MyPlayer * mp = MyPlayer.myPlayer;
    AVPlayer * player;

    @synchronized ( mp.playerLock )
    {
        if ( mp.player )
        {
            // Replace
            [mp.player replaceCurrentItemWithPlayerItem:[AVPlayerItem playerItemWithURL:url]];
        }
        else
        {
            // Create a new player
            mp.player = [AVPlayer playerWithURL:url];
        }
        
        player = mp.player;
    }

    // Start playing on a background thread
    dispatch_async ( dispatch_get_global_queue ( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^ {

        @synchronized ( mp.playerLock )
        {
            // Start playing
            mp.player.play;
        }

    } );

    return player;
}

@end

只需发送消息 [MyPlayer startPlaying:url]; 像以前一样播放 URL,但这次,它将 return 播放器。

所以在你的代码中你可以做类似

的事情
_controller.player = [MyPlayer startPlaying:url];