Autoplaying inline videos on iPhone iOS 10 using Angular

Starting with iOS 10, Safari on mobile (iPhone and iPad) started allowing developers to autoplay videos inline provided the video you are trying to play meets certain conditions. Before that, your video would not auto play inline, and when it would play, it would play full screen only. These changes were in place to prevent “websites that auto-play with sound”, if you’ve ever browsed to a site on your phone and an annoying video ad started playing, inline video autoplay is probably to blame for it but there are other legitimate uses for the inline video HTML attribute.

Video as Animated GIF

GIFs are cool we all agree, but behind the scenes they are HUGE objects and in terms of performance, GIF is definitely not the best format for the web.

It’s not uncommon for GIFs to tip the scales at several megabytes, depending on quality, frame rate, and length. If you’re trying to improve loading performance for your site and help users reduce data usage, animated GIF just isn’t compatible with that goal.

One way that you can remediate this issue is to convert these huges files to compressed lean videos which maintains a great resolution while saving huge amount of data for your users. 

Muted Autoplay

In short for a video to play inline on mobile browsers, it needs the following key attributes to be added to the video tag (depending on the mobile platform). 

  • autoplay
  • muted
  • playsinline

Only the first two are necessary for Chrome For Android but if you’re dealing with Safari, you’ll need to add the playsinline attribute which was introduced in iOS 10. A cross browser compatible code would look like:

<video src="/video.mp4" loop muted playsinline poster="/poster.png">

</video>

On most recent browsers and platforms, this would render your video inline autoplaying, with the loop attribute making your video essentially act as a GIF. 

It Doesn’t Work!

I highlighted most in the last sentence of the previous paragraph because you will most certain run into cases where it just doesn’t work. My specific case was iOS 10 and 11 iPhones running an app rendering an Angular app using a custom WebView. The video tag in that app would respect the autoplay attribute as soon as the user interacted with the page, as specified in the iOS technical guidelines for autoplay but would simply ignore the playsinline attribute and play the video full screen. It took quite a bit of Googling and trial and error to finally get it working but if you run into the same error, here are things to check for to get you up and running:

webView.configuration.allowsInlineMediaPlayback = true

if #available(iOS 10.0, *) {
webConfiguration.mediaTypesRequiringUserActionForPlayback = []
} else {
// Fallback on earlier versions
webConfiguration.mediaPlaybackRequiresUserAction = false
}

The muted attribute problem

With all these steps above enabled, I was still unable to play a video inline on an iPhone SE running iOS 10 no matter what I tried. This post brought to my attention the fact that as stated not only does the video NEEDS to be muted in order for the autoplay attribute to be taken in account, but the muted attribute itself might not work as advertised on all browsers and this unlocked the issue for me. Inspecting the video element showed me that even though the muted attribute was set in the HTML, the DOM element showed muted=false . I doubled checked with FFMpeg to make sure that indeed my mp4 file did not include an audio track and it did not! The only logical deduction was that something was broken at the browser level, prevent the muted attribute from being properly applied in the DOM. In the end a combination of using iphone-inline-video and dynamically triggering the play attribute gave me a cross-browser compatible way of playing videos inline. My final Angular code looked something like

# In my component.html

<video #gif loop muted playsinline [src]="gifUrl">
</video>



# in component.ts
import enableInlineVideo from 'iphone-inline-video';
@ViewChild('gif', { read: ElementRef }) gif: ElementRef;
ngAfterViewInit() {
const video: HTMLVideoElement = this.gif.nativeElement;
// Crucial to mute the video before for Safari autoplay to work
video.muted = true;
// Use iphone-inline-video library here after muting the video
enableInlineVideo(video);
video.oncanplay = () => {
video.muted = true;
};
const promise = video.play();
if (promise !== undefined) {
promise
.catch(err => {
// Auto-play was prevented
console.log('Autoplay was prevented');
})
.then(() => {
// Auto-play started
console.log('Autoplay started');
});
}
}

If you run into a

NotAllowedError (DOM Exception 35): The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.

This is definitely an indication that autoplay was prevented by the browser, more than likely because of an issue with the muted attribute. Use the solution listed above and see if it solves your issue.

Leverage your web developer skills for mobile development

In the world of mobile application development, you can either build applications the standard way, which means using Objective-C to write Apple iOs applications, or Java with the Android SDK for your Android applications etc etc, you get the point. But a new paradigm has appeared that is very appealing to web developers like me as complementary to a skill set I already possess: writing mobile applications using HTML, CSS and Javascript. The tool that makes this magic possible is called PhoneGap and version 1.0 has just been released to I bet, the delight of many mobile developers out there. The concept behind PhoneGap is simple:

  • Build your app using HTML and Javascript
  • Access the native phone APIs through the PhoneGap wrappers
  • Deploy to multiple platforms

The appeal here is reminiscent of the early Java slogan, “Write Once Run Anywhere” or WORA, for those who still remember, and PhoneGap is even lauching a beta for PhoneGap Build, a service that will allow you to “write your app using HTML, CSS or JavaScript, upload it to the PhoneGap Build service and get back app-store ready apps for Apple iOS, Google Android, Palm, Symbian, BlackBerry and more”.  There are a  number of Javascript frameworks out there that can be used to build apps in conjunction with PhoneGap, the  two most popular are JQuery Mobile and Sencha Touch. Both are very capable frameworks that make use of the latest advances in CSS3 and HTML5. Your choice in a guttural way would depend on your familiarity with their browser counterpart (JQuery or ExtJS). What you have to understand at the end of the day with the PhoneGap architecture is that your finished app would basically be a web page running within a browser. Here are a couple tutorials to get you going either on Sencha Touch or JQuery Mobile.

Combined as I mentioned earlier with the fact that by using HTML, CSS and Javascript the learning curve for a web developer is suddenly cut into mere hours instead of the days or even weeks required to learn and master a new heavy language like Objective C or Java, you have to wonder how come every mobile developer out there is not rushing to adopt PhoneGap. Well there are limitations when it comes to building an application using PhoneGap and here is a shortlist (By no means exhaustive, feel free to inform me of more in the comments, I will add them to the list) :

  • Running from within a browser your app won’t have the native built-in styles available unless you use CSS to mimic them. There are frameworks that have been created to that effect. Sencha Touch comes with two default themes for iOs and Android and there are JQuery Mobile Themes available as well.
  • Performance will take a hit because of the extra layer between the app and the OS.
  • Access to the some of the native phone high level functionality is sometimes limited.
  • Support is sometimes hard to come by for specific issues, since this is a community supported project.

Those issues withstanding, I still think that PhoneGap is only poised to get better, and improve support for more native functionality. I think it is complimentary to my web development skills and allow me to expand into a new market without really stepping out of my comfort zone. If you are worried about native feature support or exploiting more of the native SDK, you should definitely look into Titanium, from Appcelerator which offers to “translates your hard won web skills into native applications that perform and look just like they were written in Objective-C [iPhone and iPad] or Java [Android]”.

Here is a list of links I found useful on the matter: