AVPlayer not working with AirPlay - ios

I have a sequence of AVMutableCompositions that I am playing with AVPlayer. Everything works great when I am playing via speaker, headphones, or bluetooth. However, as soon as I connect to AirPlay, everything falls apart.
I can play one asset, and I try to switch to a new asset, I get an AVAudioSessionMediaServicesWereResetNotification and the device disconnects from AirPlay. I tried exporting the AVMutableCompositions to files and then using AVURLAssets, but this didn't seem to change anything.
Does anyone know what is going on here? It looks like I won't be able to support AirPlay...
I get the feeling that I could switch to AVAudioPlayer and this would fix the problem, but I am generating dozens of AVMutableCompositions and don't want to be reading and writing them to disk.

This is counter-intuitive, but try setting
myPlayer.allowsExternalPlayback = NO;
The documentation is not completely clear on this, but it seems that this will disallow video playback only. When I do this in my app (which uses AVPlayer), Airplay with an AVComposition works. Even the artwork shows up nicely (via an MPNowPlayingInfoCenter).

Related

Airplay background streaming like Spotify / Amazon Music

Is it possible to do Airplay audio streaming like Spotify or Amazon Music. When i setup an Airplay stream with Audio from my App the screen (on the Apple-TV) turns black and shows only the progressbar.
Is it possible to show the small hint in the top corner with all the audio information which disappears after a few Seconds and don't block the whole Apple TV Ui?
Or is this kind of a Spotify / Amazon Music privilege?
We had this problem as well. I believe that there are some bugs here in Apple's court, but we found a decent workaround that seems to be pretty safe from side effects.
We found that setting the player's allowsExternalPlayback field to NO would sometimes correctly stream the audio without the blank video screen (along with correct display of the now playing information, correct response to volume rocker etc...). However, we found that very often it would fail to play anything at all.
Doing some runtime introspection, we found that the player would always correctly buffer from the network. But when it would hit the isPlaybackLikelyToKeepUp event, it would set the player's rate field to 1 indicating that it is playing, but more often than not, not actually play the audio. No errors were reported and so from all we could tell, the player itself thinks that it is indeed playing when it is not. We found this hangup to only occur when we had set an AirPlay device for audio output.
So we found that in certain event callbacks and other key places, if we added a simple one-liner:
if( self.avPlayer.rate == 1 ){ self.avPlayer.rate = 1; }
It would kick whatever internal hold ups were causing the player to not actually AirPlay and correctly stream the audio. If the player was already correctly playing, then no harm done.

Switch between audio tracks in MPMoviePlayerController

In the app I'm currently working on I have some videos with multiple audio tracks (in different languages) and I'd like to have the ability to switch between these tracks programmatically. There is a button that allows the user to switch between them manually (which presents this screen by tapping on it: http://i.stack.imgur.com/mkUTZ.png) so I assumed this wouldn't be too hard. However, after two hours of research I haven't found anything useful. There's this StackOverflow question that suggests it's impossible to play video with multiple audio streams in the first place, but apparently that doesn't stand true anymore. There are also some examples with AVFoundation (I haven't really looked into the), but none with MPMoviePlayer or MPMoviePlayerController.
So I'd like to know if my goal is achievable with stock MPMoviePlayerController and if not, what are the good alternatives to it.

AVAudioRecorder and AirPlay Mirrioring

When I have an AVAudioRecorder Session active - (when I'm recording audio) I can't activate AirPlay mirroring on the device. Airplay mirroring just deactivates while the app is running and switches it back on when the app exits. This post seems to suggest there is no way around this.
My thoughts are to try:
using a lower level recording framework
or outputting a separate window to external display, rather than mirroring (I've tried this, it doesn't work).
Is there another way around this, or do you know whether either of these methods are known to work?
Using AudioQueue to record (like Apple's Sample Code Speak Here) rather than the AVRecorder works. A bit more work to implement, but recording continues on or off Airplay mirroring.

AVComposition breaks on Airplay

I have a video composition which I'd like to play over Airplay (without mirroring). The app works as expected when using normal Airplay mirroring, but I'd like to get the speed, reliability, and resolution bump you get from using Airplay video instead.
The problem is that when I set
player.usesAirPlayVideoWhileAirPlayScreenIsActive = YES;
...the player goes blank.
Notes:
Since I don't create separate windows for each display, they are both trying to use the same AVPlayer.
My AVVideoComposition contains different files and adds opacity ramps between them.
This unanswered question suggests that the problem is more likely due to the fact that I'm playing an AVComposition than the use of a shared player: AVComposition doesn't play via Airplay Video
Two questions:
Do I have to get rid of the player on the iPad?
Can an AVVideoComposition ever be played over AirPlay?
I can't make comments so I had to post this as an answer although it might not fully respond to the questions.
I had similar issue and at the end I found out that when AVPlayer plays AVComposition it simply doesn't display anything on the external display. That's why I had to do it myself by listening to UIScreen connection notifications.
I have to say that all worked pretty perfect. I'm checking first if there are more than one screen and if there are I simply move the AVPlayer on that screen while displaying a simple message on the device's screen that content is played on... plus the name of AirPlay device. This way I can put whatever I want on the external display and is not very complicated. Same thing is when I receive UIScreenDidConnectNotification.
That was fine until I noticed that the composition plays really choppy on the the external display. Even if it consists of only one video without any complex edits or overlays. Same video plays perfectly if I save it to the Camera Roll or if I use MPMoviePlayerController.
I've tried many things like lowering resolutions, lowering renderScale and so on but with no success.
One thing bothers me more is how actually Apple do this in iMovie - if you have AirPlay enabled and you play a project (note it's still not rendered so it must use a composition in order to display it) right after tapping play button it opens a player that plays content really smoothly on the external monitor. If you however activate AirPlay from the player it closes and start rendering the project. After that it plays it I thing by using MPMoviePlayerController.
I'm still trying to find a solution and will post back if I have any success.
So for the two questions:
I don't see why you have to get rid.
Yes it can be played but with different technique and obviously issues.
in the app .plist create a new item called:
required background modes
add a new array element called:
App plays audio or streams audio/video using AirPlay
Not sure if you have already tried this, but you don't mention it in your post.
Cheers!

How do I make my HTML5 video player autoplay on iPad, like filmon.com?

I'm trying to create an HTML5 video player to automatically start streaming video. I searched a lot but I didn't achieve my goal.
Then I found www.filmon.com, where all videos start to play automatically on iPad.
Does anyone know how they did it? I looked at their JS files, but I cannot make mine start automatically.
Apple has specifically disabled every method and workaround to autoplay video on iPads and iPhones (the "autoplay" attribute, and Javascript solutions like triggering hidden link's "onclick" event).
I have yet to find a way to autoplay on iPads and it looks like Apple is continuing to squash all efforts to do it. They state, "In Safari on iPhone OS (for all devices, including iPad), where the user may be on a cellular network and be charged per data unit, autobuffering and autoplay are disabled. No data is loaded until the user initiates it."
As a quick update I just checked out Filmon.com and the videos there no longer seem to be autoplaying on an iPad. Example: http://demand.filmon.com/distant-roads-173-cnd-ontario-ca-1 autoplays on Chrome, but not on the iPad.
I don't think that iphone or ipad play streams automatically due to high traffic.
Why don't you play it manually using script at document ready?
somewhat like this:
window.onload=function(){
var audio = document.getElementById('audio');
audio.play();
}

Resources