Why HTML5 video doesn't play in IOS 8 WebApp(webview)? - ios

Simple HTML5 video plays on safari browser. but after adding it to home screen(Standalone WebApp), it doesn't work. It is working on iOS7 but stopped working on iOS8.
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta name="apple-mobile-web-app-capable" content="yes" />
<title>HTML5 Video Standalone Test</title>
<style>
body{
margin:0;
}
</style>
</head>
<body>
<video src="http://www.jplayer.org/video/m4v/Big_Buck_Bunny_Trailer_480x270_h264aac.m4v" autoplay="autoplay" controls="true" webkit-playsinline />
</body>
</html>
Please help. Is there any solution for this?

Video playback is broken on standalone applications in IOS 8.0.2

Looks like iOS 8.3 fixes this issue. I have a standalone web app that uses an audio element, and it's working as expected now. FINALLY!

Confirming
Packaged cordova App cannot load video
Added:
<preference name="AllowInlineMediaPlayback" value="true"/>
to config.xml and
webkit-playsinline
to the video element.
The UI says video is Loading, while video.networkStatus remains 2 (NETWORK_LOADING) and video.readyState 0 (HAVE_NOTHING)
Safari playback works
Home screen launcher playback does not work
For the same webapp that worked in ios Safari, the homescreen version does not play videos either, and crashes the webapp when trying to change the source of the video.
I don't like apple :|

I have two apps that use HTML5 video. One stopped working, the other not. There were two differences:
The one that still works added the source tags to the video tag AFTER adding the video tag to the DOM.
The app that still works has autoplay set to false (<video autoplay="false">...</video>)
The first one made no difference, the second one made the app work again.

I think I found a workaround for the audio not working. I can't really explain why this fix is working, but it is.
Here's what my old code looked like:
// Create the audio tag
var sprite = document.createElement('audio');
var id = document.createAttribute('id');
id.nodeValue = 'audio_sprite';
var src = document.createAttribute('src');
src.nodeValue = 'my-audio-sprite.mp3';
sprite.setAttributeNode( id );
sprite.setAttributeNode( src );
// Add it to the DOM
var body = document.getElementsByTagName('body')[0];
body.appendChild( sprite );
// Play/Pause to load the audio.
sprite.play();
sprite.pause();
Here's what I'm doing now.
// Grab an existing DOM element and create an audio tag.
var body = document.getElementById('hover');
body.innerHTML += '<audio id="audio_sprite"><p>Audio not supported</p></audio>';
// Apply the SRC to the audio tag.
// Q: Why don't we just do that in the step above?
// A: I'm not really sure why, but iOS8 doesn't like it. Sorry this is so ugly.
var sprite = document.getElementById( 'audio_sprite' );
sprite.src = 'my-audio-sprite.mp3';
// Once the metadata is loaded, call play/pause so we can play the audio later.
sprite.addEventListener('loadedmetadata', function() {
sprite.play();
sprite.pause();
});
In my mind, both should work however, in practice, only the second one does for iOS8. I hope this helps someone.

I got this working by finding the video element, then creating a source element in script (not in the html) - strange I know:
var video = document.getElementById('theVideo');
var source = document.createElement('source');
source.src = fileLocation
source.type = "video/mp4"
video.appendChild( source );
video.load();
I also accept this is an old issue, but I came across it as I was testing on an iPad that has iOS 8.0.2 installed and it caught me out for a day.

Related

Video tag not working on iPhone Safari or Chrome and certain iPads

I'm at the end of my rope with a certain issue of my videos not playing on my iPhone 6 browsers (Safari and Chrome) and certain ipads. It works great on desktop browsers, Android Chrome and even my iPad mini in Safari. I've researched this for a while now, including Stack Overflow but everything I've tried still doesn't play the video on my iPhone (only shows the initial frame image). Here is my video test page where I'm making edits, my code below and what I've tried to fix it based on research:
<section id="video-wrap">
<video class="video <?php the_field('header_video_class'); ?>" autoplay muted loop>
<source src="/video/<?php the_field('header_video'); ?>.mp4" type="video/mp4">
<source src="/video/<?php the_field('header_video'); ?>.ogg" type="video/ogg">
<source src="/video/<?php the_field('header_video'); ?>.webm" type="video/webm">
</video><!-- /video -->
<div id="video-wrapper">
<div class="video-caption">
<?php the_title(); ?>
</div><!-- /content -->
</div>
</section>
I've tried adding the controls parameter back in, no luck
I've tried adding the video source within the video tag and removing the additional source tags, no luck
I've also compressed the heck out of my video. This test example is currently 640 × 360, H.264, AAC. Still no luck.
I've tried removing the video caption overlay in case that was conflicting. No luck.
WHAT AM I MISSING? Thanks in advance for any help!
New Answer (working) :
Well I somehow missed this one little detail "only shows the initial frame image". I've misread the Question as "video does not even try to work" (because it can happen with some models/brands vs H.264 codec).
Acoording to this blog aticle : html5 Video Autoplay on iOS and Android...
Your code should look like (also use low-res MP4 version) :
<video class="video" playsinline autoplay muted loop>
Finally also check : Webkit policy for video section. Maybe it'll be useful to trick the machne.
Older Answer :
I've also compressed the heck out of my video. This test example is currently 640 × 360, H.264, AAC. Still no luck.
Your H.264 video is encoded with incompatible Profile : High # Level 3.0.
Solution : Re-encode with choosing Main # level 3.1 (also can try level 4.0).
Since no iOS hardware here, test these re-encode :
Main profile #L3.1 : clip-intro-low_v2.mp4
Baseline profile #L3.0 : clip-intro-low_v3.mp4
PS: You may have a similar issue to this Question (in case it's useful to you).
There is a trick to load a video tag in the safari browser. We simply just need to reload the page where the video tag is placed.
And to reload the page we can use this code
var ua = navigator.userAgent.toLowerCase();
if (ua.indexOf('safari') != -1) {
if (ua.indexOf('chrome') > -1) {
}
else {
// Check if video tag exists
if (jQuery(document).find('.hero-slideshow .hero-media-wrap video').length > 0) {
if (window.location.href.indexOf('reload') == -1) {
window.location.replace(window.location.href + '?reload');
}
}
}
}
This might not be a permanent solution but we can use this code as quickfix.
setTimeout(function (){
$('.hero-slideshow .slides .hero-mp4 video').once().each(function(){
$(this).parent('.hero-mp4').show();
$(this).get(0).play();
});
}, 2000);
Add source to the video tag and add this attribute too.
preload="auto"
<video width="100%" height="100%" loop muted playsinline preload="auto" class="hero-video media-document mac video">
<source src="VideoSrc" type="video/mp4"></source>
</video>

IOS Memory buildup when changing IFRAME src with angular/Embedding youtube in cordova?

I'm afraid im having the same probem as this unasnwered question.
I have a blank IFRAME In my cordova ionic IOS App for embedded YouTube videos.
I change the NG-SRC="" of iframe by clicking Next Video. But upon testing it appears that the phone/cordova/webview is caching the old content of the iframes. I can only get through 20 videos or so before crashing out of memory.
I have tried using angular.element.remove() to remove the iframe as well as setting the iframe src to blank first, and neither seemed to affect how much memory is in use, per Xcode. I've also tried the cordova plugin ClearCache and that didnt clear any memory either.
Please help! Is there a better way to embed youtube in a cordova app?
I have spent weeks working on this all to have it crashing down around me (no pun intended)
My Video view is like:
<ion-view view-title="Random Video">
<iframe id="youtube" sandbox="allow-scripts allow-same-origin" ng-src="{{video.url | trustAsResourceUrl}}" frameborder="0" allowfullscreen></iframe>
<h4>{{video.title}}</h4>
<button ng-click="nextVideo()">
</ion-view>
My controller is like:
angular.module('starter.controllers')
.controller('VideoCtrl', function(VideoService) {
$scope.video = {};
$scope.nextVideo = function() {
$scope.video = null; //doesnt seem to help
//$scope.$destroy(); //doesn't help
//angular.element(document.querySelector( '#youtube' )).attr("src", " ");
//angular.element(document.querySelector( '#youtube' )).remove();
//neither of the above 2 remove any memory
VideoService.getVideo().then(function(response){
$scope.video = response.data;
});
}
$scope.nextVideo();
});
Note, when I load my app onto a website instead, and load in chrome, I can cycle through videos without seeing the memory usage go up (looking at taskmgr.exe at least)
It might seem like setting the iframe to an empty string should be enough, but for some browsers and some situations it isn't. It might be necessary to recursively delete event listeners and elements one by one. Maybe surprisingly, the recursive method (1) below is faster than just setting to an empty string (2):
1.Recursive
while (box.lastChild) {
box.removeChild(box.lastChild);
}
2. Setting empty string
myNode.innerHTML = '';
See https://stackoverflow.com/a/3955238/1158376 for reference.
Additionally, in the recursive approach, one might need to apply special treatment to some items, for example first remove event listeners, nullify functions (http://javascript.crockford.com/memory/leak.html), and use dedicated cleanup methods, like with jQuery (http://javascript.info/tutorial/memory-leaks).
Another strategy you could try is to load a new web page with a fresh iframe for every video you play. Loading a new page should enable the browser to release the previously claimed memory.

setMuted or setVolume do not work on iPad in MediaElement.js

It appears that neither volume controls nor mute/unmute work on iPad. Did anyone encounter this problem before? Pretty straightforward functionality, no errors, just silent fail.
var player;
$(document).ready(function () {
player = new MediaElementPlayer('#player', {});
});
function mute() {
player.setMuted(true)
// player.setVolume(0) does not work either on iPad
}
function unmute() {
player.setMuted(false)
}
HTML:
<audio id="player" controls="controls">
<source type="audio/mp3" src="intro.mp3" /> </audio>
Nevermind. Since MediaElement.js uses native <audio> controls on iPad, according to Safari HTML5 Audio and Video guide, it is not possible to control HTML5 audio volume via script:
On iOS devices, the audio level is always under the user’s physical control. The volume property is not settable in JavaScript. Reading the volume property always returns 1.
https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html
... need to program a workaround for iPads.

Hide HTML5 video in UIWebView if it cannot be played

I have a UIWebView that contains a HTML5 video. The SRC of the video is dynamic, and uses HTTP Live Streaming. If, for whatever reason, the video cannot be played, the user is presented with the "play-with-a-slash-though-it" icon, indicating it cannot be played. I'd like to handle this situation by hiding the video player and presenting a message to the user instead. Are there any callbacks that I can subscribe to that will allow me to achieve this?
UPDATE
Thanks to codeghost's answer, I was able to resolve my problem. However, I thought it would be useful for future readers to see a code example:
<html>
<body>
<video id='video' width='640' height='480' controls='controls' preload='none' autoplay='autoplay'>
<source src='http://some.video.com'/>
Your browser does not support the video tag.
</video>
<script type='text/javascript'>
var video = document.getElementById('video')
video.addEventListener('error', function(event) {
if(event.type == "error")
{
alert("There was an error getting the video.");
}
}, true);
</script>
</body>
</html>
You could do this in the web page by adding a javascript handler for error event on the video tag.

HTML5 AutoPlay mp3 on IPad

I am trying to Autoplay an mp3 file using html5 on ipad but its not working
Here is my code
<audio src="1.mp3" autoplay="" controls="" onended="this.play()"></audio>
The iPad does not support autoplaying of video and audio files. This is a design decision.
I found a way to auto-play video. I think is working on audio, also.
It works if you append/empty every time the video element from the div.
function addListeners()
{
// loop for each list item
$('#mscroll li').each(function looping(index)
{
// onclick...
$(this).click(function onItemClick()
{
// empty left column and description
$("#divplayer").empty();
// append video tag
$("#divplayer").append('<video width="'+video_width+'" height="'+video_height+'" controls="controls"><source src="'+videos_array[index].mp4+'" autoplay/></video>');
$('video').get(0).play();
});
});
}
I have tested this on my Ipad, iOS 5.1.1
Here is a pretty detailed overview of mobile audio and tricks to make it work, created in 2013, so quite recent:
http://pupunzi.open-lab.com/2013/03/13/making-html5-audio-actually-work-on-mobile/
Good luck!

Resources