如何让我的AVPlayer在后台运行?

时间:2022-06-02 20:35:24

I've done my homework... been reading here, the docs, googling, *ing... but still no luck in making my sound stick when the user makes the app go into the background.

我做了我的家庭作业…在这里阅读,文档,谷歌搜索,堆叠……但当用户让我的应用进入后台时,我还是没办法把我的声音棒弄出来。

What I have done so far: Added the UIBackgroundModes, audio to the plist-file.

到目前为止我所做的是:添加uibackgroundmode,音频到plist-file。

First this code:

首先这段代码:

radioAudio = [[AVAudioSession alloc] init];
[radioAudio setCategory:AVAudioSessionCategoryPlayback error:nil];
[radioAudio setActive:YES error:nil];

Then this:

那么这个:

NSString *radioURL = @"http://xxx.xxx.xxx/radio.m3u";
radioPlayer = [[AVPlayer playerWithURL:[NSURL URLWithString:radioURL]] retain];

But as soon as the user hits the home-button, my sound dies.

但一旦用户按下home键,我的声音就会消失。

I also found this, but not added yet cuase some stuff I've read says it is not needed;

我也发现了这个,但还没有添加一些我读过的东西说它是不需要的;

newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];
     if (newTaskId != UIBackgroundTaskInvalid && bgTaskId != UIBackgroundTaskInvalid)
        [[UIApplication sharedApplication] endBackgroundTask: bgTaskId];
bgTaskId = newTaskId;

Right now I have no idea where I should go to make my AVPlayer let the radio sing while the user does other stuff on the phone. I am testing this on an iPhone 4 with 4.2. Building it for 4.0.

现在我不知道我应该去哪里让我的AVPlayer在用户在手机上做其他事情的时候让收音机唱歌。我正在4.2版的iPhone 4上测试这个功能。建筑为4.0。

Anyone have any suggestions what I should do?

有人建议我该怎么做吗?

6 个解决方案

#1


41  

Had the same problem, but found a solution for this..

我也有同样的问题,但是我找到了解决的办法。

Look here: https://devforums.apple.com/message/395049#395049

看这里:https://devforums.apple.com/message/395049 # 395049

The content of the above link:

以上链接内容:


Replace APPNAME with your own app name!

用您自己的应用程序名替换APPNAME !

Im on iOS 4.2.1

我在iOS 4.2.1

EDIT: Working with iOS5 + 6 + 7 beta so far

编辑:目前使用iOS5 + 6 + 7测试版

Add UIBackgroundModes in the APPNAME-Info.plist, with the selection App plays audio

在APPNAME-Info中添加uibackgroundmode。plist,选择应用播放音频

Then add the AudioToolBox framework to the folder frameworks.

然后将AudioToolBox框架添加到文件夹框架中。

In the APPNAMEAppDelegate.h add:

APPNAMEAppDelegate。h添加:

#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>

so it look like this:

它是这样的

...
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
...

In the APPNAMEAppDelegate.m add the following:

APPNAMEAppDelegate。m添加以下:

// 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. Changing the default output audio route
UInt32 doChangeDefaultRoute = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof(doChangeDefaultRoute), &doChangeDefaultRoute);

into the

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

but before the two lines:

但在这两句话之前

[self.window addSubview:viewController.view];
[self.window makeKeyAndVisible];

Build your project and see if theres any error, If not, try debug on Device insted of the Simulator, it CAN bug on simulator.

构建您的项目,看看是否有任何错误,如果没有,尝试调试设备insted的模拟器,它可以在模拟器上bug。

Hope this helps others with same problem..

希望这能帮助其他有同样问题的人。

#2


28  

UPDATE IOS 11.2 with Swift 4:

更新IOS 11.2与Swift 4:

Now if you are using AVPlayer to play music files you should also configure MPNowPlayingInfoCenter.default() to show now playing info on the lock screen.

现在,如果您正在使用AVPlayer播放音乐文件,您还应该配置MPNowPlayingInfoCenter.default()以显示现在在锁定屏幕上播放的信息。

Below code will show now playing controls on the screen but it won't be able to respond any commands.

下面的代码将显示在屏幕上播放控件,但是它不能响应任何命令。

If you also want to controls to work you should check apple's sample project here: https://developer.apple.com/library/content/samplecode/MPRemoteCommandSample/Introduction/Intro.html#//apple_ref/doc/uid/TP40017322

如果你还想控制工作,你应该检查苹果的样例项目:https://developer.apple.com/library/content/samplecode/mpremotecommandsample/tion/intro.html #//apple_ref/doc/uid/TP40017322。

Apple sample code covers all but i find it confusing.

苹果的示例代码涵盖了所有内容,但我发现它令人困惑。

If you want to play sound and show controls on the lock screen these steps will do just fine.

如果您想在锁屏上播放声音并显示控件,这些步骤就可以了。

IMPORTANT NOTE: If you are NOT using AVPlayer to play sound. If you are using some third party libraries to generate sound or playback a sound file you should read comments inside the code. Also if you are using ios simulator 11.2 you won't be able to see any controls on lock screen. You should use a device to see it work.

重要提示:如果你没有使用AVPlayer播放声音。如果您正在使用一些第三方库来生成声音或回放一个声音文件,您应该阅读代码中的注释。另外,如果你正在使用ios模拟器11.2,你将无法在锁屏上看到任何控件。您应该使用一个设备来查看它的工作。


1- Select project -> capabilites -> set background modes ON -> tick Audio, AirPlay and Picture in Picture

1-选择project -> capabilites ->在-> tick音频、AirPlay和图片上设置背景模式

如何让我的AVPlayer在后台运行?

2- AppDelegate.swift file should look like this :

2 - AppDelegate。swift文件应该是这样的:

import UIKit

import AVFoundation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate
{

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
    {
        // Override point for customization after application launch.

        do
        {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
            try AVAudioSession.sharedInstance().setActive(true)

         //!! IMPORTANT !!
         /*
         If you're using 3rd party libraries to play sound or generate sound you should
         set sample rate manually here.
         Otherwise you wont be able to hear any sound when you lock screen
         */
            //try AVAudioSession.sharedInstance().setPreferredSampleRate(4096)
        }
        catch
        {
            print(error)
        }
        // This will enable to show nowplaying controls on lock screen
        application.beginReceivingRemoteControlEvents()

        return true
    }
}

3- ViewController.swift should look like this:

3 - ViewController。斯威夫特应该是这样的:

import UIKit

import AVFoundation
import MediaPlayer

class ViewController: UIViewController
{

    var player : AVPlayer = AVPlayer()

    override func viewDidLoad()
    {
        super.viewDidLoad()


        let path = Bundle.main.path(forResource: "music", ofType: "mp3")
        let url = URL(fileURLWithPath: path!)

        // !! IMPORTANT !!
        /*
            If you are using 3rd party libraries to play sound 
            or generate sound you should always setNowPlayingInfo 
            before you create your player object.

            right:
            self.setNowPlayingInfo()
            let notAVPlayer = SomePlayer()

            wrong(You won't be able to see any controls on lock screen.):
            let notAVPlayer = SomePlayer()
            self.setNowPlayingInfo()
         */

        self.setNowPlayingInfo()
        self.player = AVPlayer(url: url)

    }


    func setNowPlayingInfo()
    {
        let nowPlayingInfoCenter = MPNowPlayingInfoCenter.default()
        var nowPlayingInfo = nowPlayingInfoCenter.nowPlayingInfo ?? [String: Any]()

        let title = "title"
        let album = "album"
        let artworkData = Data()
        let image = UIImage(data: artworkData) ?? UIImage()
        let artwork = MPMediaItemArtwork(boundsSize: image.size, requestHandler: {  (_) -> UIImage in
            return image
        })

        nowPlayingInfo[MPMediaItemPropertyTitle] = title
        nowPlayingInfo[MPMediaItemPropertyAlbumTitle] = album
        nowPlayingInfo[MPMediaItemPropertyArtwork] = artwork

        nowPlayingInfoCenter.nowPlayingInfo = nowPlayingInfo
    }

    @IBAction func startPlayingButtonPressed(_ sender: Any)
    {
        self.player.play()
    }

OLD ANSWER IOS 8.2:

老回答IOS 8.2:

Patrick's answer is totally right.

帕特里克的回答完全正确。

But i'm gonna write what i do for ios 8.2:

但是我要写ios8.2的内容

I add my app's info.plist required background modes like below:

我添加了我的应用程序的信息。plist所需的后台模式如下:

如何让我的AVPlayer在后台运行?

And in my AppDelegate.h i add these imports:

在我AppDelegate。h我加上这些进口:

#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>

Then in my AppDelegate.m i wrote application didFinishLaunchingWithOptionsthis exactly like below:

然后在我AppDelegate。我写了应用didFinishLaunchingWithOptionsthis,如下所示:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

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

    return YES;
}

Now App keeps playing music even if screen is locked :)

现在App继续播放音乐,即使屏幕被锁定:)

#3


10  

I have successfully made audio run in the background by adding the following to my applicationDidFinishLaunching

通过在应用程序didfinishlaunching中添加以下内容,我成功地在后台运行了音频

// Registers this class as the delegate of the audio session.
[[AVAudioSession sharedInstance] setDelegate: self];    
// Allow the app sound to continue to play when the screen is locked.
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

#4


3  

iOS 9 Swift

iOS 9迅速

All you should need is add the following to your didFinishLaunchingWithOptions

您需要做的就是向didFinishLaunchingWithOptions添加以下内容

do  {
    try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
} catch {
    //TODO
}

#5


1  

You have a good example of a GPS background app that plays sounds even when in background :

你有一个很好的GPS背景应用的例子,即使在背景下也能播放声音:

http://www.informit.com/articles/article.aspx?p=1646438&seqNum=5

http://www.informit.com/articles/article.aspx?p=1646438&seqNum=5

In this example, AudioToolbox is used.

在本例中,使用AudioToolbox。

I did a test myself and it works : create a simple project that monitors the GPS post (UIBackgroundModes location) , and every x received position, play a sound using

我自己做了一个测试,它起作用了:创建一个简单的项目来监视GPS站(uibackgroundmode定位),并且每一个x接收到的位置,使用它来播放声音

AudioServicesPlaySystemSound(soundId);

AudioServicesPlaySystemSound(soundId);

Then if you put audio as part of your UIBackgroundModes and the sounds will be played, even if the application isn't in foreground anymore.

如果你把音频作为uibackgroundmode的一部分,声音就会播放,即使应用程序不在前台。

I've made such a test and it works ok !

我做过这样的测试,效果不错!

(I didn't manage to get it working with AVPlayer so I fallbacked to AudioToolbox)

(我没能让它与AVPlayer一起工作,所以我选择了AudioToolbox)

#6


0  

I've the same problem and I found solution in Apple Docs:https://developer.apple.com/library/ios/qa/qa1668/_index.html

我遇到了同样的问题,我在苹果文档中找到了解决方案:https://developer.apple.com/library/ios/qa1668/_index.html。

Q: How do I ensure my media will continue playing when using AV Foundation while my application is in the background?

问:当我的应用程序在后台时,如何确保我的媒体在使用AV Foundation时继续播放?

A: You must declare your app plays audible content while in the background, and assign an appropriate category to your audio session. See also Special Considerations for Video Media.

答:你必须声明你的应用程序在后台播放音频内容,并为你的音频会话分配一个合适的类别。请参见视频媒体的特殊注意事项。

#1


41  

Had the same problem, but found a solution for this..

我也有同样的问题,但是我找到了解决的办法。

Look here: https://devforums.apple.com/message/395049#395049

看这里:https://devforums.apple.com/message/395049 # 395049

The content of the above link:

以上链接内容:


Replace APPNAME with your own app name!

用您自己的应用程序名替换APPNAME !

Im on iOS 4.2.1

我在iOS 4.2.1

EDIT: Working with iOS5 + 6 + 7 beta so far

编辑:目前使用iOS5 + 6 + 7测试版

Add UIBackgroundModes in the APPNAME-Info.plist, with the selection App plays audio

在APPNAME-Info中添加uibackgroundmode。plist,选择应用播放音频

Then add the AudioToolBox framework to the folder frameworks.

然后将AudioToolBox框架添加到文件夹框架中。

In the APPNAMEAppDelegate.h add:

APPNAMEAppDelegate。h添加:

#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>

so it look like this:

它是这样的

...
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
...

In the APPNAMEAppDelegate.m add the following:

APPNAMEAppDelegate。m添加以下:

// 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. Changing the default output audio route
UInt32 doChangeDefaultRoute = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof(doChangeDefaultRoute), &doChangeDefaultRoute);

into the

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

but before the two lines:

但在这两句话之前

[self.window addSubview:viewController.view];
[self.window makeKeyAndVisible];

Build your project and see if theres any error, If not, try debug on Device insted of the Simulator, it CAN bug on simulator.

构建您的项目,看看是否有任何错误,如果没有,尝试调试设备insted的模拟器,它可以在模拟器上bug。

Hope this helps others with same problem..

希望这能帮助其他有同样问题的人。

#2


28  

UPDATE IOS 11.2 with Swift 4:

更新IOS 11.2与Swift 4:

Now if you are using AVPlayer to play music files you should also configure MPNowPlayingInfoCenter.default() to show now playing info on the lock screen.

现在,如果您正在使用AVPlayer播放音乐文件,您还应该配置MPNowPlayingInfoCenter.default()以显示现在在锁定屏幕上播放的信息。

Below code will show now playing controls on the screen but it won't be able to respond any commands.

下面的代码将显示在屏幕上播放控件,但是它不能响应任何命令。

If you also want to controls to work you should check apple's sample project here: https://developer.apple.com/library/content/samplecode/MPRemoteCommandSample/Introduction/Intro.html#//apple_ref/doc/uid/TP40017322

如果你还想控制工作,你应该检查苹果的样例项目:https://developer.apple.com/library/content/samplecode/mpremotecommandsample/tion/intro.html #//apple_ref/doc/uid/TP40017322。

Apple sample code covers all but i find it confusing.

苹果的示例代码涵盖了所有内容,但我发现它令人困惑。

If you want to play sound and show controls on the lock screen these steps will do just fine.

如果您想在锁屏上播放声音并显示控件,这些步骤就可以了。

IMPORTANT NOTE: If you are NOT using AVPlayer to play sound. If you are using some third party libraries to generate sound or playback a sound file you should read comments inside the code. Also if you are using ios simulator 11.2 you won't be able to see any controls on lock screen. You should use a device to see it work.

重要提示:如果你没有使用AVPlayer播放声音。如果您正在使用一些第三方库来生成声音或回放一个声音文件,您应该阅读代码中的注释。另外,如果你正在使用ios模拟器11.2,你将无法在锁屏上看到任何控件。您应该使用一个设备来查看它的工作。


1- Select project -> capabilites -> set background modes ON -> tick Audio, AirPlay and Picture in Picture

1-选择project -> capabilites ->在-> tick音频、AirPlay和图片上设置背景模式

如何让我的AVPlayer在后台运行?

2- AppDelegate.swift file should look like this :

2 - AppDelegate。swift文件应该是这样的:

import UIKit

import AVFoundation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate
{

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
    {
        // Override point for customization after application launch.

        do
        {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
            try AVAudioSession.sharedInstance().setActive(true)

         //!! IMPORTANT !!
         /*
         If you're using 3rd party libraries to play sound or generate sound you should
         set sample rate manually here.
         Otherwise you wont be able to hear any sound when you lock screen
         */
            //try AVAudioSession.sharedInstance().setPreferredSampleRate(4096)
        }
        catch
        {
            print(error)
        }
        // This will enable to show nowplaying controls on lock screen
        application.beginReceivingRemoteControlEvents()

        return true
    }
}

3- ViewController.swift should look like this:

3 - ViewController。斯威夫特应该是这样的:

import UIKit

import AVFoundation
import MediaPlayer

class ViewController: UIViewController
{

    var player : AVPlayer = AVPlayer()

    override func viewDidLoad()
    {
        super.viewDidLoad()


        let path = Bundle.main.path(forResource: "music", ofType: "mp3")
        let url = URL(fileURLWithPath: path!)

        // !! IMPORTANT !!
        /*
            If you are using 3rd party libraries to play sound 
            or generate sound you should always setNowPlayingInfo 
            before you create your player object.

            right:
            self.setNowPlayingInfo()
            let notAVPlayer = SomePlayer()

            wrong(You won't be able to see any controls on lock screen.):
            let notAVPlayer = SomePlayer()
            self.setNowPlayingInfo()
         */

        self.setNowPlayingInfo()
        self.player = AVPlayer(url: url)

    }


    func setNowPlayingInfo()
    {
        let nowPlayingInfoCenter = MPNowPlayingInfoCenter.default()
        var nowPlayingInfo = nowPlayingInfoCenter.nowPlayingInfo ?? [String: Any]()

        let title = "title"
        let album = "album"
        let artworkData = Data()
        let image = UIImage(data: artworkData) ?? UIImage()
        let artwork = MPMediaItemArtwork(boundsSize: image.size, requestHandler: {  (_) -> UIImage in
            return image
        })

        nowPlayingInfo[MPMediaItemPropertyTitle] = title
        nowPlayingInfo[MPMediaItemPropertyAlbumTitle] = album
        nowPlayingInfo[MPMediaItemPropertyArtwork] = artwork

        nowPlayingInfoCenter.nowPlayingInfo = nowPlayingInfo
    }

    @IBAction func startPlayingButtonPressed(_ sender: Any)
    {
        self.player.play()
    }

OLD ANSWER IOS 8.2:

老回答IOS 8.2:

Patrick's answer is totally right.

帕特里克的回答完全正确。

But i'm gonna write what i do for ios 8.2:

但是我要写ios8.2的内容

I add my app's info.plist required background modes like below:

我添加了我的应用程序的信息。plist所需的后台模式如下:

如何让我的AVPlayer在后台运行?

And in my AppDelegate.h i add these imports:

在我AppDelegate。h我加上这些进口:

#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>

Then in my AppDelegate.m i wrote application didFinishLaunchingWithOptionsthis exactly like below:

然后在我AppDelegate。我写了应用didFinishLaunchingWithOptionsthis,如下所示:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

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

    return YES;
}

Now App keeps playing music even if screen is locked :)

现在App继续播放音乐,即使屏幕被锁定:)

#3


10  

I have successfully made audio run in the background by adding the following to my applicationDidFinishLaunching

通过在应用程序didfinishlaunching中添加以下内容,我成功地在后台运行了音频

// Registers this class as the delegate of the audio session.
[[AVAudioSession sharedInstance] setDelegate: self];    
// Allow the app sound to continue to play when the screen is locked.
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

#4


3  

iOS 9 Swift

iOS 9迅速

All you should need is add the following to your didFinishLaunchingWithOptions

您需要做的就是向didFinishLaunchingWithOptions添加以下内容

do  {
    try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
} catch {
    //TODO
}

#5


1  

You have a good example of a GPS background app that plays sounds even when in background :

你有一个很好的GPS背景应用的例子,即使在背景下也能播放声音:

http://www.informit.com/articles/article.aspx?p=1646438&seqNum=5

http://www.informit.com/articles/article.aspx?p=1646438&seqNum=5

In this example, AudioToolbox is used.

在本例中,使用AudioToolbox。

I did a test myself and it works : create a simple project that monitors the GPS post (UIBackgroundModes location) , and every x received position, play a sound using

我自己做了一个测试,它起作用了:创建一个简单的项目来监视GPS站(uibackgroundmode定位),并且每一个x接收到的位置,使用它来播放声音

AudioServicesPlaySystemSound(soundId);

AudioServicesPlaySystemSound(soundId);

Then if you put audio as part of your UIBackgroundModes and the sounds will be played, even if the application isn't in foreground anymore.

如果你把音频作为uibackgroundmode的一部分,声音就会播放,即使应用程序不在前台。

I've made such a test and it works ok !

我做过这样的测试,效果不错!

(I didn't manage to get it working with AVPlayer so I fallbacked to AudioToolbox)

(我没能让它与AVPlayer一起工作,所以我选择了AudioToolbox)

#6


0  

I've the same problem and I found solution in Apple Docs:https://developer.apple.com/library/ios/qa/qa1668/_index.html

我遇到了同样的问题,我在苹果文档中找到了解决方案:https://developer.apple.com/library/ios/qa1668/_index.html。

Q: How do I ensure my media will continue playing when using AV Foundation while my application is in the background?

问:当我的应用程序在后台时,如何确保我的媒体在使用AV Foundation时继续播放?

A: You must declare your app plays audible content while in the background, and assign an appropriate category to your audio session. See also Special Considerations for Video Media.

答:你必须声明你的应用程序在后台播放音频内容,并为你的音频会话分配一个合适的类别。请参见视频媒体的特殊注意事项。