I'm developing a live social app, it's able users have text chat when they are watching gameplay.
I found AVPlayer will stop video when user tap voice input on the keyboard.
How do I fixed this issue ?
This will happen because when you record your voice, the sound coming from the video will interrupt the recording (voice coming out of the phone speaker will heavily distort sound going through the microphone) Thus the video will automatically be stopped.
Please try adding the code below: (only need to set it once)
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient, error: nil)
AVAudioSession.sharedInstance().setActive(true, error: nil)
my solution is add observer of
UITextInputCurrentInputModeDidChange
I have no idea how to playing video and using voice input at the same time ( just like facebook iOS behavior )
however I can resume the video after voice input is done ( just like youtube iOS behavior )
func textInputMethodDidChange(notification: NSNotification) {
print("textInputMethodDidChange")
if self.textInputMode == nil || self.textInputMode?.primaryLanguage != "dictation" {
self.player.play()
}
}
Related
i am using ReplayKit's RPScreenRecorder.shared().startCapture method to record screen and microphone, but i am facing an issue. if i play AVPlayer while ScreenRecording, the microphone stops recording audio. Below are two scenario. in first everything working fine but in second voice recording not working.
started AVPlayer and then start screenRecording, AVPlayer's Audio stop and my screen and microphone start recording
started screenRecording and working fine. then i start the AVPlayer and when AVPlayer play the audio the voice recording is stopped
After digging a lot i found a solution. Default AVFoundation Allow to use either Microphone or Speaker at a time and ReplayKit is incompatible with AVPlayer content. So if we want to use both of them at a time we need to set AVAudioSession's Category to AVAudioSessionCategoryMultiRoute.
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryMultiRoute)
} catch let error as NSError {
print(error)
}
do {
try AVAudioSession.sharedInstance().setActive(true)
} catch let error as NSError {
print(error)
}
I think it is a system limitation
As in apple official documents it is written
ReplayKit is incompatible with AVPlayer content.
You can read details here
I have successfully implemented valid and working AVFoundation video recording functionality into my application. That said, any playing audio e.g. Apple Music or a YouTube video playing in the background is interrupted / immediately paused whenever the video recording begins.
My question is: How could I allow the globally-playing audio to continue to play without interruption when recording video?
I was able to do this by adapting the answer here to Swift.
I was doing this to prevent a silent tutorial video in my app from interrupting any currently playing audio. Setting the AVAudioSession category to "ambient" using the setCategory(_:mode:options:) method seems to be the key here.
Apple seems to suggest using this method within the application didFinishLaunchingWithOptions method, but I think their example is targeted towards audio apps. So depending on your needs, you may want to put it there.
Here's the adapted code, I placed it within the view controller that is showing the video:
import AVFoundation
...
override func viewDidLoad() {
super.viewDidLoad()
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(.ambient, mode: .default, options: .mixWithOthers)
} catch {
print(error.localizedDescription)
}
}
Developing an iOS app which plays back audio messages in segments (not continuous playback). When the app is opened, I initialize the audio session with the following options.
func _initAudioSesh() {
let audioSession = AVAudioSession.sharedInstance()
do {
if #available(iOS 10.0, *) {
try audioSession.setCategory(
AVAudioSessionCategoryPlayAndRecord,
mode: AVAudioSessionModeVoiceChat,
options: [
AVAudioSessionCategoryOptions.defaultToSpeaker,
AVAudioSessionCategoryOptions.allowBluetooth,
AVAudioSessionCategoryOptions.allowBluetoothA2DP
]
)
} else {
try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord)
}
} catch {
print("Setting category to AVAudioSessionCategoryPlayback failed.")
}
}
Then, when ready to playback audio, I grab focus using setActive(true) and release focus using setActive(false)
The issue I'm encountering is that in the app, the hardware volume buttons only work when audio is playing, otherwise, the buttons do nothing. I was able to hack around this by ALWAYS holding setActive(true), but that hack is ugly and causes other issues. Has anyone else experienced volume buttons not working/adjusting in-app, and only working when audio is actively being played?
As soon as I leave the app, audio adjustment works, as soon as I bring it back into focus, it stops working unless I begin to play audio.
I've tried messing with how & when I create the audio session, with no success.
This ended up being a result of a specific library we're using (react-native-system-settings), which has now been patched. If other users encounter issues, the fix seems to be around allowing UI to show in VolumeView. Otherwise, it doesn't allow the hardware buttons to affect volume.
I am currently using the following statement to detect music:
if MPMusicPlayerController.systemMusicPlayer().playbackState == .Playing {
print("There is music playing")
}
Great, however this will only work for iTunes player, and not music that might be coming from a different app, specifically talking about Spotify.
I don't need to know the song being played, simply whether there is anything playing at all, so I can decide whether I provide my own background music for my game or not.
Edit: ideally the solution should cover any 3rd party music program, not just Spotify.
Given iOS: How do I detect if music is playing in any background music app?
the Swift version would be:
let isOtherAudioPlaying = AVAudioSession.sharedInstance().isOtherAudioPlaying()
However, the developer docs suggest that starting with iOS 8.0 you should use secondaryAudioShouldBeSilencedHint instead:
if (AVAudioSession.sharedInstance().secondaryAudioShouldBeSilencedHint()) {
print("another application with a non-mixable audio session is playing audio")
}
Im using YouTube Helper Library to play YouTube videos on my iOS application
Here are link of Library
I just need a way to continue audio (or video) playing in background ,
So when user click on home button i need him to be able to hear the voice
of the video ,
even when he lock his device i need to him to be able to control the sound and
click next and back button for audio playing ..
How i can achieve that on YouTube Helper Library ?
NOTE: many application do that and they exist on app-store like iMusic , Video Tube ,MusicTV , MB2
Playing background video (or voice) is against the YouTube TOS. You can not do it with this library for sure, even if you figure out a workaround, your app would be taken down because of TOS violation.
About playing sounds in background:
You have to set the AVAudioSession category to AVAudioSessionCategoryPlayback and add the audio value to the UIBackgroundModes key in your information property list file.
NSError *setCategoryError = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &setCategoryError];
I have tested this code on iOS 7 and up only, so it may not work for earlier versions.
From Apple docs:
AVAudioSessionCategoryPlayback The category for playing recorded music
or other sounds that are central to the successful use of your app.
When using this category, your app audio continues with the Silent
switch set to silent or when the screen locks. (The switch is called
the Ring/Silent switch on iPhone.) To continue playing audio when your
app transitions to the background (for example, when the screen
locks), add the audio value to the UIBackgroundModes key in your
information property list file.
see references here and here
You need to enable it when app enter background. Remember to check your app is in background
func playerView(_ playerView: YTPlayerView, didChangeTo state: YTPlayerState) {
if state == .paused {
playerView.playVideo()
}
}