html5 Video tag style messed in Ionic CSS

I’m not a fan of videoangular myself either, I’d much prefer a simpler, more straight forward video player themed to match ionics look and feel (maybe a project today?)

But like I mentioned above, I’d recommend using a video service providers embed option just to keep a consistent look and feel

Hi Mike, do you know if the Ionic has the same video tag issue on iPhone?

As far as i know, there shouldn’t be any issues with ios (much better/richer webview).

Again, the issue isn’t fully ionic, but androids webview

Thanks Mike. Next, I will run my Ionic app on iPhone to verify that.

Hi,

I’m experiencing this issue on an Android 4.1.2 device and I prefer not to use an external library like videoangular or an external video service provider.
Mike (@mhartington) said that the problem is the default video player in older Android browsers, but I created a simple test app based on the ionic start default project and found that removing the <link href="lib/ionic/css/ionic.css" rel="stylesheet"> makes the video tag show a much nicer player (see images below).
The code I’m using for the test video is:

<video id="video1" width="480" preload="metadata" controls webkit-playsinline>
	<source type="video/mp4" src="http://www.w3schools.com/html/mov_bbb.mp4"></source>
	<source type="video/ogg" src="http://www.w3schools.com/html/mov_bbb.ogg"></source>
	Your browser does not support HTML5 video.
</video>

I don’t really understand the reason, because I looked into ionic.css and couldn’t find anything relevant related to the video elements. Any idea?.

Thanks & regards,
  Rafa.


With ionic.css:

Without ionic.css:

After some testing I’ve finally managed to fix the appearance of the player by creating it inside a local iframe.

I found issues adding the code of the video element (which is dynamic) into the iframe, because writing directly to the iframe.contentDocument (as suggested here) made the app crash in Android 4.1.2, but using a data URL worked. This is how the code looks:

var DATA_SRC_PREFIX = "data:text/html;charset=utf-8,";
var HTML5_PLAYER_DATA_CODE = '<html><head></head><body>' + 
	'<video poster="{{poster}}" preload="metadata" controls webkit-playsinline>' +
	'<source ng-repeat="src in playerSrcList track by $index" ng-src="{{trustResourceUrl(src.url)}}" type="{{src.format}}">' +
	'Your browser doesn\'t support HTML5 video.' +
	'</video>' + 
	'</body></html>';

var compiledPlayer = $compile("<div>" + HTML5_PLAYER_DATA_CODE + "</div>")(scope);
$timeout(function(){ //Need timeout to wait to get the interpolated html code
	scope.model.iFrameDataSrc = $sce.trustAsResourceUrl(
		DATA_SRC_PREFIX + escape(compiledPlayer.html())
	);
});							

Anyway I still wonder how ionic.css affects the appearance of the video player.

Hope it helps.
  Rafa

Hmm, yeah I would like to know why as well…
The video playing uses shadowDom, which we don’t have access to with css…

We’ll look into this and see whats going on. Can you make an issue for this and post the two images as well?

Done. https://github.com/driftyco/ionic/issues/1821

Hi and thanks for the code.

I’ve been trying to use the code to solve the iframe loading problem, it but I simply can’t figure out how to use it correctly.
Any chance to make a Plunkr, so we can learn the correct way of using it?

Many thanks in advance.

Ok, I got it working as a directive.
It’s working great, and doesn’t need $compile nor $timeout.

On the directive’s file:

.directive('dynamicUrl', [function () {
    return {
        restrict: 'A',
        link: function postLink(scope, element, attr) {
            element.attr('src', attr.dynamicUrlSrc);
        }
    }
}])

On the template file:

<iframe src="" dynamic-url dynamic-url-src="{{URL}}" frameborder="0" allowfullscreen></iframe>

The solution came from:

EDIT: Sorry, it DOES needs $timeout… If its triggered without it, it will be too fast, and the DOM wont have been updated yet. See my plnkr in the post below for a working solution.

Yes, please. I’m getting the same problem now in iOS8 and would love to get around it somehow but can’t figure out how to use your iFrame workaround.

Ok, here’s a plnkr of what I did.

One crucial step is the timeout on the directive, as you need to wait for the dom to be built, so it can be manupulated by the directive.

Hi mhartington,
I tried your example its working fine for your video url but when i am passing other YouTube url its not working.
Could not find where is the problem is any security with other videos.

http://www.youtube.com/watch?v=znK652H6yQM

Sounds like a case of not whitelisting the url…something that tripped me up too

For me the video would play fine on iOS and not play at all on Android. urbgimtam’s solution absolutely worked for me. Thanks.

The true reason the CSS is messed up in video and audio tags is that the styles in ionic’s _range.scss are leaking to the tag’s shadow DOM. input[type="range"] selector and its pseudo-selectors cause the messed styles…

yeah but it’s shadow dom, normal css has no effect on it. Thats the whole point of shadow dom

Then its obviously a bug at least for iOS safari 8- (in my case)

Not just iOS, as the same is true in Android stock browser, and Chrome for Android, It doesn’t matter if its packaged in Cordova, Crosswalk or just viewed as regular html, the result is the same. Nice catch, lukasmlady.

Well I’ll be, it is causing the issue…hmmm interesting, so much for shadow dom I guess.

Thanks for the pointing this out! I’ll note it on the open issue!

1 Like