在后台使用Avplayer播放视频是否可行?

18

我正在使用Avplayer来显示视频片段,当我返回(应用在后台运行)时,视频停止播放。如何使视频继续播放?

我搜索了关于后台任务和后台线程的信息,iOS仅支持在后台播放音乐(不支持视频) http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html

以下是有关在后台播放视频的讨论:

1) https://discussions.apple.com/thread/2799090?start=0&tstart=0

2) http://www.cocoawithlove.com/2011/04/background-audio-through-ios-movie.html

但是AppStore中有很多可以在后台播放视频的应用程序,例如

Swift Player: https://itunes.apple.com/us/app/swift-player-speed-up-video/id545216639?mt=8&ign-mpt=uo%3D2

SpeedUpTV: https://itunes.apple.com/ua/app/speeduptv/id386986953?mt=8


2
对于这个问题进行研究,给你点赞! - Niru Mukund Shah
8个回答

13

此方法支持所有可能性:

  • 用户锁定屏幕;
  • 列表项;
  • 按下主页按钮;

只要您有运行 AVPlayer 实例,iOS 将防止设备自动锁定。

首先,您需要从 Info.plist 文件配置应用程序以支持后台音频,在 UIBackgroundModes 数组中添加音频元素。

然后将这些方法放入您的 AppDelegate.m 中的

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions:

[[AVAudioSession sharedInstance] setDelegate: self];    
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

而且 #import <AVFoundation/AVFoundation.h>

然后在控制AVPlayer的视图控制器中使用。

-(void)viewDidAppear:(BOOL)animated
{
  [super viewDidAppear:animated];
  [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
  [self becomeFirstResponder];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [mPlayer pause];    
    [super viewWillDisappear:animated];
    [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
    [self resignFirstResponder];
}

然后回复

 - (void)remoteControlReceivedWithEvent:(UIEvent *)event {
        switch (event.subtype) {
            case UIEventSubtypeRemoteControlTogglePlayPause:
                if([mPlayer rate] == 0){
                    [mPlayer play];
                } else {
                    [mPlayer pause];
                }
                break;
            case UIEventSubtypeRemoteControlPlay:
                [mPlayer play];
                break;
            case UIEventSubtypeRemoteControlPause:
                [mPlayer pause];
                break;
            default:
                break;
        }
    }

如果用户按下主页按钮(此时播放会被暂停并淡出),需要另一个技巧来恢复播放。

当您控制视频的播放(我有播放方法)时,请设置

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];

以及相应的方法将被调用,以启动计时器并恢复播放。

- (void)applicationDidEnterBackground:(NSNotification *)notification
{
    [mPlayer performSelector:@selector(play) withObject:nil afterDelay:0.01];
}

我在后台播放视频时成功了,感谢大家。


http://www.edumobile.org/iphone/iphone-programming-tutorials/parsing-an-xml-file/ - Vishal Khatri
嗨@V.K., 我刚刚按照您的指示设置了播放视频音频背景。但是,如果我打开锁屏,只有在按下Home按钮时才会播放。音频将在几秒钟后停止。 :( 我该如何解决这个问题? - duongvanthai
  • (BOOL)canBecomeFirstResponder { return YES; } //.... 将此代码添加到 AvPlayer 屏幕中并在设备上检查
- Vishal Khatri
@ZAFAR007:所有必需的代码都在这里了。请检查并告诉我你在寻找什么? - Vishal Khatri
@VishalKhatri 感谢您的回复。我在我的应用程序中使用了上述代码,但它只在屏幕锁定时起作用。当我按下主页按钮时,这个NotificationCenter.default.addObserver(self, selector: #selector(applicationDidEnterBackground),name:NSNotification‌​.Name.UIApplicationD‌​idEnterBackground, object: nil)函数被调用,但音乐没有恢复?有什么想法吗? - ZAFAR007
显示剩余3条评论

3

有没有其他的方法可以在后台播放视频? - Vishal Khatri
@Horst,我们能否在AVPlayer中也拥有像MPMoviePlayerViewController一样的功能,即当应用程序进入后台时视频暂停,并在前台恢复播放时间? - Zalak Patel
您可以在此处了解更多信息:https://developer.apple.com/library/ios/qa/qa1668/_index.html - Horst

2

接受答案的 Swift 版本。

在委托中:

AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, error: nil)
AVAudioSession.sharedInstance().setActive(true, error: nil)

在控制AVPlayer的视图控制器中
override func viewDidAppear(animated: Bool) {
    UIApplication.sharedApplication().beginReceivingRemoteControlEvents()
    self.becomeFirstResponder()
}

override func viewWillDisappear(animated: Bool) {
    mPlayer.pause()
    UIApplication.sharedApplication().endReceivingRemoteControlEvents()
    self.resignFirstResponder()
}

别忘了“import AVFoundation”


var mPlayer = AVPlayer() - MVZ

2

使用Avplayer不可能播放背景音乐/视频。但是使用MPMoviePlayerViewController可以实现。我在我的一个应用程序中使用这个播放器,这个应用程序已经成功运行到了appstore。


不,它是可能的。看看我的答案。对我来说完美地运作。谢谢你的建议。将来我会尝试使用MPMoviePlayerViewController。 - Vishal Khatri
@V.K. 我们可以使用 AVPlayer 在应用程序进入后台时暂停视频,并在应用程序进入前台时恢复播放吗?这是使用 AVPlayer 可能实现的吗? - Zalak Patel

2

试用以下代码片段,我已经将其集成到我的应用程序中,对我非常有用..希望这对你也有效!!

按照以下步骤进行操作:

  • Add UIBackgroundModes in the APPNAME-Info.plist, with the selection App plays audio
  • Then add the AudioToolBox framework to the folder frameworks.
  • In the APPNAMEAppDelegate.h add:

    -- #import < AVFoundation/AVFoundation.h>

    -- #import < AudioToolbox/AudioToolbox.h>

  • In the APPNAMEAppDelegate.m add the following:

    // Set AudioSession

     NSError *sessionError = nil;
    
        [[AVAudioSession sharedInstance] setDelegate:self];
    
        [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError];
    
  • /* Pick any one of them */

  • // 1. Overriding the output audio route

// 将音频路由重定向到扬声器 // UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; // AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);

========================================================================

// 2. 更改默认的输出音频路由

UInt32 doChangeDefaultRoute = 1;

AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof(doChangeDefaultRoute), &doChangeDefaultRoute);

进入其中
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  • 在这两行代码之前:

    [self.window addSubview:viewController.view];

    [self.window makeKeyAndVisible];

编程愉快!


1
当您控制视频的播放(我有播放方法)时,请设置以下内容:[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];并调用相应的方法,启动计时器并恢复播放。
  • (void)applicationDidEnterBackground:(NSNotification *)notification { [mPlayer performSelector:@selector(play) withObject:nil afterDelay:0.01]; }
它对我很有效。
- Vishal Khatri
你应该注明这段代码的原始来源,Patrick Rorth: https://devforums.apple.com/thread/90684?start=0&tstart=0 - Chris

1
除了fattomhk的回答之外,以下是您可以做的来实现视频转发到应用程序进入前台后的正确时间:
  • 在应用程序进入后台时获取正在播放的视频的currentPlaybackTime并将其存储在lastPlayBackTime
  • 将应用程序进入后台时的时间存储下来(可能在userDefault中)
  • 再次获取应用程序进入前台时的时间
  • 计算后台和前台时间之间的duration
  • 将视频的当前播放时间设置为lastPlayBackTime+duration

在后台中,我该如何播放视频的音乐? - Vishal Khatri
1
从视频中提取音轨,并同时播放。 - rptwsthi
缓冲延迟怎么样? - Teoman shipahi

0
如果您正在使用WebView播放视频,可以使用JavaScript来处理在后台播放视频。
strVideoHTML = @"<html><head><style>body.........</style></head> <body><div id=\"overlay\"><div id=\"youtubelogo1\"></div></div><div id=\"player\"></div> <script> var tag = document.createElement('script'); tag.src = \"http://www.youtube.com/player_api\"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); var player; events: { 'onReady': onPlayerReady, } }); } function onPlayerReady(event) { event.target.playVideo(); } function changeBG(url){ document.getElementById('overlay').style.backgroundImage=url;} function manualPlay() {  player.playVideo(); }  function manualPause() {  player.pauseVideo(); }  </script></body> </html>";

NSString *html = [NSString stringWithFormat:strVideoHTML,url, width, height,videoid;
webvideoView.delegate = self;
[webvideoView loadHTMLString:html baseURL:[NSURL URLWithString:@"http://www.your-url.com"]];

在视图消失时调用

strscript = @"manualPlay();
[webvideoView stringByEvaluatingJavaScriptFromString:strscript];

0

我想补充一些东西,因为某些原因成为了我的罪魁祸首。我长时间使用 AVPlayer 和后台播放而没有问题,但这一次我就是无法使它工作。

我发现当你进入后台时,AVPlayer 的 rate 属性有时似乎会下降到 0.0(即暂停),因此我们需要始终 KVO 检查速率属性,或者至少在进入后台时检查。如果速率下降到 0.0,并且我们可以假设用户想要播放(即用户没有故意在远程控制中点击暂停,电影结束等),我们需要再次调用 AVPlayer 上的 .play()

据我所知,AVPlayer 没有其他开关可防止其在应用程序进入后台时暂停。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接