[英]How do I get my AVPlayer to play while app is in background?
我已經完成了我的功課......一直在這里閱讀,文檔,谷歌搜索,stackoverflowing......但是當用戶讓應用程序進入后台時,我的聲音仍然沒有運氣。
到目前為止我所做的:將 UIBackgroundModes、音頻添加到 plist 文件。
首先這段代碼:
radioAudio = [[AVAudioSession alloc] init];
[radioAudio setCategory:AVAudioSessionCategoryPlayback error:nil];
[radioAudio setActive:YES error:nil];
然后這個:
NSString *radioURL = @"http://xxx.xxx.xxx/radio.m3u";
radioPlayer = [[AVPlayer playerWithURL:[NSURL URLWithString:radioURL]] retain];
但是一旦用戶按下主頁按鈕,我的聲音就會消失。
我也發現了這個,但還沒有添加,因為我讀過的一些東西說不需要;
newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];
if (newTaskId != UIBackgroundTaskInvalid && bgTaskId != UIBackgroundTaskInvalid)
[[UIApplication sharedApplication] endBackgroundTask: bgTaskId];
bgTaskId = newTaskId;
現在我不知道我應該去哪里讓我的 AVPlayer 讓收音機唱歌,而用戶在手機上做其他事情。 我正在 4.2 的 iPhone 4 上對此進行測試。 為 4.0 構建它。
有人對我應該做什么有任何建議嗎?
使用Swift 4更新IOS 11.2:
現在,如果您使用AVPlayer播放音樂文件,您還應該配置MPNowPlayingInfoCenter.default()
以在鎖定屏幕上顯示正在播放的信息。
下面的代碼將顯示現在在屏幕上播放控件但它無法響應任何命令。
如果你還想讓控件工作,你應該在這里查看apple的示例項目: https : //developer.apple.com/library/content/samplecode/MPRemoteCommandSample/Introduction/Intro.html#//apple_ref/doc/uid/TP40017322
Apple示例代碼涵蓋了所有內容,但我發現它令人困惑。
如果你想在鎖定屏幕上播放聲音並顯示控件,這些步驟就可以了。
重要說明:如果您不使用AVPlayer播放聲音。 如果您使用某些第三方庫來生成聲音或播放聲音文件,您應該閱讀代碼中的注釋。 此外,如果您使用ios模擬器11.2,您將無法在鎖定屏幕上看到任何控件。 您應該使用設備查看它是否有效。
1-選擇項目 - >功能 - >將背景模式設置為開 - >勾選音頻,AirPlay和畫中畫
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應如下所示:
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做的事情:
我添加了我的應用程序的info.plist所需的背景模式,如下所示:
在我的AppDelegate.h中,我添加了這些導入:
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
然后在我的AppDelegate.m中,我寫了應用程序didFinishLaunchingWithOptionsthis,如下所示:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
return YES;
}
現在App即使屏幕被鎖定也會繼續播放音樂:)
有同樣的問題,但找到了解決方案..
請看這里: https : //devforums.apple.com/message/395049#395049
以上鏈接的內容:
用您自己的應用名稱替換APPNAME
!
我在iOS 4.2.1上
編輯:到目前為止使用iOS5 + 6 + 7測試版
在APPNAME-Info.plist
添加UIBackgroundModes
,選擇App播放音頻
然后將AudioToolBox
框架添加到文件夾框架。
在APPNAMEAppDelegate.h
添加:
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
所以它看起來像這樣:
...
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
...
在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);
進入
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
但在兩行之前:
[self.window addSubview:viewController.view];
[self.window makeKeyAndVisible];
構建你的項目,看看是否有任何錯誤,如果沒有,嘗試在模擬器的設備上調試,它可以在模擬器上出錯。
希望這有助於其他同樣的問題..
我通過在applicationDidFinishLaunching
添加以下內容,成功地在后台運行音頻
// 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];
iOS 9 Swift
您應該只需要將以下內容添加到didFinishLaunchingWithOptions中
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
} catch {
//TODO
}
你有一個很好的GPS背景應用程序示例,即使在后台播放聲音:
http://www.informit.com/articles/article.aspx?p=1646438&seqNum=5
在此示例中,使用了AudioToolbox。
我自己做了一個測試並且它有效:創建一個監視GPS帖子( UIBackgroundModes
location
)的簡單項目,以及每個x接收位置,播放聲音使用
AudioServicesPlaySystemSound(soundId);
然后,如果您將audio
作為UIBackgroundModes
一部分並且將播放聲音,即使應用程序不再處於前台。
我做了這樣的測試,它運作正常!
(我沒有設法讓它與AVPlayer一起使用,所以我退回到AudioToolbox)
我遇到了同樣的問題,我在Apple Docs中找到了解決方案: https : //developer.apple.com/library/ios/qa/qa1668/_index.html
問:在應用程序處於后台時,如何確保在使用AV Foundation時我的媒體將繼續播放?
為Swift 5工作
以下是我為讓 avPlayer 正在播放的視頻在后台播放音樂而做的 4 件事。 我按照@AndriySavran 的回答中的 Apple 方向鏈接以及其他一些內容進行操作。
1- 在 AppDelegate 的didFinishLaunching
我放了:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default, options: [.mixWithOthers, .allowAirPlay])
print("Playback OK")
try AVAudioSession.sharedInstance().setActive(true)
print("Session is Active")
} catch {
print(error)
}
// whatever other code that you use ...
return true
}
2- 按照@LeoDabus 的回答進行操作。 在您的Signing & Capabilties
> Background Modes
(如果背景模式不存在,然后從功能中選擇它)> 勾選Audio, Airplay, and Picture in Picture
3- 在具有AVPlayer
的視圖控制器中,添加.didEnterBackgroundNotification
和.willEnterForegroundNotification
通知
var player: AVPlayer?
var playerItem: AVPlayerItem? // your AVPlayer should be initialized with this
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self,
selector: #selector(appDidEnterBackground),
name: UIApplication.didEnterBackgroundNotification, object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(appWillEnterForeground),
name: UIApplication.willEnterForegroundNotification, object: nil)
}
4- 為選擇器方法添加來自 Apple 鏈接的代碼
@objc func appDidEnterBackground() {
if let player = player {
if !player.isPlaying { // if the player isn't playing no need to disable the playerItemTrack
return
}
}
guard let tracks = playerItem?.tracks else { return } // this is assuming your AVPlayer is initialized with a class property AVPlayerItem like from step 3
for playerItemTrack in tracks {
guard let assetTrack = playerItemTrack.assetTrack else { continue }
// Find the video tracks.
if assetTrack.hasMediaCharacteristic(AVMediaCharacteristic.visual) {
// Disable the track.
playerItemTrack.isEnabled = false
}
}
}
@objc func appWillEnterForeground() {
guard let tracks = playerItem?.tracks else { return }
for playerItemTrack in tracks {
guard let assetTrack = playerItemTrack.assetTrack else { continue }
// Find the video tracks.
if assetTrack.hasMediaCharacteristic(AVMediaCharacteristic.visual) {
// Enable the track.
playerItemTrack.isEnabled = true
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.