Giter Site home page Giter Site logo

fregante / iphone-inline-video Goto Github PK

View Code? Open in Web Editor NEW
2.1K 69.0 301.0 1.59 MB

๐Ÿ“ฑ Make videos playable inline on the iPhone (prevents automatic fullscreen)

Home Page: https://npm.im/iphone-inline-video

License: MIT License

JavaScript 98.61% HTML 1.39%
iphone autoplaying-videos polyfill playsinline

iphone-inline-video's Introduction

No longer needed ๐ŸŽ‰

iOS now supports this natively since v10. So long, and thanks for all the videos!

iphone-inline-video

Make videos playable inline on Safari on iPhone (prevents automatic fullscreen)

gzipped size Travis build status npm version

This enables iOS 10's playsinline attribute on iOS 8 and iOS 9 (almost a polyfill). It lets you:

  • Play videos without going fullscreen on the iPhone (demo)
  • Play silent videos without user interaction
  • Autoplay silent videos with the autoplay attribute (demo)
  • Use videos as WebGL/ThreeJS textures (demo)

Demo

Main features

  • <2KB, standalone (no frameworks required)
  • No setup: include it, call enableInlineVideo(video), done
  • No custom API for playback, you can just call video.play() on click
  • Supports audio
  • Supports autoplay on silent videos
  • Doesn't need canvas
  • Doesn't create new elements/wrappers
  • It works with existing players like jPlayer
  • Disabled automatically on iOS 10+

Limitations:

  • Needs user interaction to play videos with sound (standard iOS limitation)
  • Limited to iPhone with iOS 8 and 9. iPad support needs to be enabled separately. It's disabled on Android.
  • The video framerate depends on requestAnimationFrame, so avoid expensive animations and similar while the video is playing. Try stats.js to visualize your page's framerate
  • Known issues

Install

Pick your favorite:

<script src="dist/iphone-inline-video.min.js"></script>
npm install --save iphone-inline-video
var enableInlineVideo = require('iphone-inline-video');
import enableInlineVideo from 'iphone-inline-video';

Usage

You will need:

  • a <video> element with the attribute playsinline (required on iOS 10 and iOS 11. Why?)

     <video src="file.mp4" playsinline></video>
  • the native play buttons will still trigger the fullscreen, so it's best to hide them when iphone-inline-video is enabled. More info on the .IIV CSS class

     .IIV::-webkit-media-controls-play-button,
     .IIV::-webkit-media-controls-start-playback-button {
         opacity: 0;
         pointer-events: none;
         width: 5px;
     }
  • the activation call

     // one video
     var video = document.querySelector('video');
     enableInlineVideo(video);
     // or if you're already using jQuery:
     var video = $('video').get(0);
     enableInlineVideo(video);
     // or if you have multiple videos:
     $('video').each(function () {
     	enableInlineVideo(this);
     });

Done! It will only be enabled on iPhones and iPod Touch devices.

Now you can keep using it just like you would on a desktop. Run video.play(), video.pause(), listen to events with video.addEventListener() or $(video).on(), etc...

BUT you still need user interaction to play the audio, so do something like this:

enableInlineVideo(video);
video.addEventListener('touchstart', function () {
	video.play();
});

If at some point you want to open the video in fullscreen, use the standard (but still prefixed) webkitEnterFullScreen() API, but it has some caveats.

Usage with audio-less videos

If your video file doesn't have an audio track, then must set a muted attribute:

<video muted playsinline src="video.mp4"></video>

Usage with autoplaying videos

The autoplay attribute is also supported, if muted is set:

<video autoplay muted playsinline src="video.mp4"></video>

Muted videos can also be played without user interaction โ€” which means that video.play() doesn't need to be called inside an event listener:

<video muted playsinline src="video.mp4"></video>
setTimeout(function () { video.play(); }, 1000); // example

Usage on iPad

The iPad already supports inline videos so IIV is not enabled there.

The only reason to enabled IIV on iPad:

  • you want muted videos to autoplay, or
  • you want to play videos without user interaction

To enabled IIV on the iPad:

enableInlineVideo(video, {
	iPad: true
});

Notes about iOS 10

New features in iOS 10 and iOS 11:

  • videos play inline:

    <video playsinline src="video.mp4"></video>
  • muted videos play inline without user interaction:

    <video muted playsinline src="video.mp4"></video>
    setTimeout(function () { video.play(); }, 1000); // example
  • muted videos autoplay inline:

    <video autoplay muted playsinline src="video.mp4"></video>

Essentially everything that this module does, so iphone-inline-video will be automatically disabled on iOS 10-11. Make sure you use the playsinline attribute.

License

MIT ยฉ Federico Brigante

iphone-inline-video's People

Contributors

bfred-it avatar binarykitchen avatar dennis-van-bennekom avatar fregante avatar ivanschwarz avatar timdp avatar webpapaya avatar wpsmithtwc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iphone-inline-video's Issues

Load via require

How could i load this module via require?

require('iphone-inline-video') doesnt seem to work

ReferenceError: navigator is not defined

[email protected] test /home/michael-heuberger/Development/videomail-client
tape test/**/*.test.js

/home/michael-heuberger/Development/videomail-client/node_modules/iphone-inline-video/dist/iphone-inline-video.common-js.js:74
var isNeeded = /iPhone|iPod/i.test(navigator.userAgent);
                                   ^
ReferenceError: navigator is not defined
    at Object.<anonymous> (/home/michael-heuberger/Development/videomail-client/node_modules/iphone-inline-video/dist/iphone-inline-video.common-js.js:74:36)
    at Module._compile (module.js:435:26)
    at Object.Module._extensions..js (module.js:442:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Module.require (module.js:366:17)
    at require (module.js:385:17)
    at Object.<anonymous> (/home/michael-heuberger/Development/videomail-client/src/wrappers/visuals/replay.js:3:31)
    at Module._compile (module.js:435:26)
    at Object.Module._extensions..js (module.js:442:10)

Muting video

Hi @bfred-it
Setting muted=true does not work on the iPhone.
Also unable to adjust volume on the video. Is this a limitation?

FYI, there is an audio track in the video.

CSS to hide play buttons

In commit a4ddfc8:

video::-webkit-media-controls-start-playback-button {
    display:none;
}

was changed to:

.IIV::-webkit-media-controls-play-button,
.IIV::-webkit-media-controls-start-playback-button {
    opacity: 0;
    pointer-events: none;
    width: 5px;
}

and the comment was updated to read "the native play buttons will still trigger the fullscreen, so it's best to hide them (without breaking the video controls)".

I'm wondering if the 5px is necessary. I'm not seeing any issue in removing it, and opacity + pointer-events seems to be sufficient. I also don't see an issue with display: none, but it would be helpful to understand the specific purpose and what it affects.

Looping video on mobile

Is is possible to make autoplay video loop on mobile?

I'm using a <video> tag with autoplay & loop enabled. Works fine on desktop and the initial load on mobile, but won't repeat / loop.

Failed to set currentTime

I'm getting an error while using chrome's devtools in device mode.

Super minor bug, but makes testing in general slightly more difficult.

screen shot 2016-04-11 at 3 34 09 pm

Running inside ionic 2 framework

I have been trying to use iphone-inline-video in my ionic 2 app but without success. The video still opens full screen. Are you aware of anyone using it successfully in ionic 2?

Make seeking more reliable

Currently IIV relies on the seeking event to detect user seeks with .currentTime = <double> but with I found out I can intercept .currentTime's getter/setter without breaking its functionality with something like:

const time = Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'currentTime');

Object.defineProperty(video, 'currentTime', {
    get: () => {
        console.log('getting time')
        return time.get.call(video);
    },
    set: t => {
        console.log('setting time', t)
        return time.set.call(video, t);
    }
});

This would probably pave the way for #8

Option to make it lazy (detect more browsers)

  1. Some Android browsers force the video fullscreen, but which ones?
  2. IIV could actually be break things if enabled where not tested and there's no easy way to detect whether the video is not being updated.
  3. Feature detection means that users will see a video flash fullscreen for up to a second, this is true at least on iOS

Possible options:

  • whitelist, only iPhone/iPod now, but could be extended
  • whitelist+lazy, like above but also watch for automatic fullscreen to detect point #โ€‹1
  • lazy only: always watch for automatic fullscreen, it lets webkit-playsinline-enabled browsers work without this IIV, but point #โ€‹3

Possible API, default options:

enableInlineVideo(video, {
    enabled: 'auto',
    lazy: false // ideally this would default to true, but point #2
});

Demos not working properly

I noticed that the demos aren't working properly due to the video being used (https://media.w3.org/2010/05/sintel/trailer.mp4) not loading correctly (ranging from timeout, to ssl error, to ...)

I'd recommend including a (small) sample MP4 file into this repo, and referring to it using a service such as https://rawgit.com/

ended event not firing on mobile.

Given the following code:

  • The video loads when the load method is called. (I am not using autostart or loop).
  • The 'data is loaded' is written once to the notification pane.
  • The video starts playing on iphone / desktop browser but, not on ipad.
  • No ended event is ever triggered by the video element on the phone or ipad, but in a desktop browser it is triggered.

Is there another method of detecting the video has ended.
Is it possible to get the player to work on an ipad?
any pointers would be appreciated, I am happy to try and help get it working.

jQuery(document).ready(function() {

    console.log('loading video tags');

    var count = 1;
    var video = jQuery('#bannerVideo').get(0);
    makeVideoPlayableInline(video, false);
    video.addEventListener('ended', function() {
        jQuery('div.notify').html('video has ended');
    });
    video.addEventListener('loadeddata', function() {
        jQuery('div.notify').html('data is loaded' + count++);
        window.setTimeout(function() { video.play(); }, 3000);
    });
    video.load();

});

The html looks like this

        <div class="video-container">
                <div class="notify">notify</div>
                <video width="100%" preload="metadata" id="bannerVideo">
                <source
                    src="wp-content/uploads/2016/04/video.mp4"
                    type="video/mp4"
                    alt="">
                </video>
        </div>

Used as a Three.js Texture

Do you know if this should work as a texture in Three.js? I'm trying it but it' still popping out into a full screen player.

There is a script error but I can't debug it at the moment, getting this in jsconsole

:0link
Script error.
"@", "stalled"
"@", "timeupdate"
:0link
Script error.
"@", "progress"
"@", "progress"
:0link
Script error.
:0link
Script error.

TypeError: Attempted to assign to readonly property.

I'm getting this error on iPhone 5, iOS 9.3

TypeError: Attempted to assign to readonly property.

Here is my video constructor

if(!video){
            video = document.createElement( 'video' );
            //video.width = 2048;
           // video.height = 1024;
            video.autoplay = true;
            video.loop = true;
            video.crossOrigin = '';
            video.preload = 'auto';
            video.setAttribute('webkit-playsinline', 'webkit-playsinline');


        }

        video.src = cdnPrefix + "/"+ sceneObject.video;

        const videoPlayer = document.querySelector('video');
        makeVideoPlayableInline(videoPlayer);

If I remove 'use Strict' I get

TypeError: null is not an object (evaluating 'n[a]={}')

Any ideas what that could be?

Can't toggle mute/sound

Hello, i use your solution to autoplay inline a video with the muted option set, but i can't figure out how i can play video sound afterwards.

i try to set video.muted = true/false on a button click but nothing actually happens. How can i trigger video button from an external click?

Loop?

Seems like the loop attribute isn't supported. Is this true?

iPad in-line video autoplay

Dear Federico,
thank you for the code. It works perfectly on iPhone. Could you please show a working example of init code for iPad, using this:

if (/iPhone|iPad|iPod/i.test(navigator.userAgent)) {
    makeVideoPlayableInline(video, false /* hasAudio */, false /* false = run everywhere */);
}

I dont have any access to iPad at the moment and cant test the code, so would appreciate your help. Thanks in advance!

Videomails can't be played on iPhones

Hello again

I have added your library to my web app for recording videos online, see https://www.videomail.io
But it seems your library still can't help playing the recorded videos for iPhones.

How to reproduce:

  1. Just record a videomail from that page
  2. Send it to yourself
  3. Open that videomail on your iPhone mail app
  4. Click on the link and it should open the view page on Safari
  5. But no picture, no video, nothing.

Any ideas why?

"ReferenceError: Can't find variable: Symbol"

Happened on videomail.io with your latest version.

Useragent was Mozilla/5.0 (BB10; Touch) AppleWebKit/537.35+ (KHTML, like Gecko) Version/10.3.2.858 Mobile Safari/537.35+

And the matching code line was
var _Symbol = void 0 === Symbol ? function(description) {

In case if you want to debut, it is there
https://videomail.io/js/main-a35a84d532.min.js:11704:undefined

Video playback for Chrome / Android browsers

Hi mate,

I truly love what you build here! It works so well on Safari iOS and it is just perfectly solid.

However, when I open my website on iOS Chrome or any Android browser, it doesn't trigger the video. Do you know if there is something we (I) can do to make this work?

Just for reference, this is the link: http://www.happiness-design.com

I'm much looking forward to your feedback, and thanks again ๐Ÿ‘

Cheers,
Chris Constandse

Detect webview

When it runs inside a webview with webview.allowsInlineMediaPlayback = YES the video runs with the plugin but there is no need to (I've then experience some delays in events like play); it would be good if your plugin could detect this case and not fire.

Anyway great work your plugin is amazing.

Audio keeps playing in the background

Hello, when an inline video playing, i press the home button or switch applications, but the video is still playing.
In this case, is there a way to pause?

Ideas

Personal wishlist/notes

  • play audio via AudioContext to add volume/mute support and only require the first touch to play: #41 (comment)
  • return a Promise on .play(): https://developers.google.com/web/updates/2016/03/play-returns-promise
  • allow toggling between muted and unmuted #56
    • allow setting of mute via mute attribute instead of parameter (added in v2)
  • wait for the resource selection algorithm if <source> is used and .currentSrc is empty (i.e. .networkState === .NETWORK_NO_SOURCE || .NETWORK_EMPTY)
    • improve and test support for video src update (i.e. verify the video state and the audio track loading) (added in v1.8)
  • allow complete enabling and disabling of IIV (would be nice for #33)
    • extend the prototype automatically and enable it on request, this prevents late activation errors
    • allow enabling via webkit-playsinline
      • add automatic mode (enableInlineVideo(/*no params*/))
  • make sure that playing multiple videos with audio behaves as expected (one stops, the other plays)
  • look into automatically stopping the audio when the user switches tab
  • handle airplay somehow

Seek and seeking are not fired

These events are prevented because the script works by doing the seeking continuously, so they fire all the time and make no sense to the developer. Perhaps I can filter some of them reliably.

I could also proxy them (and timeupdate) from audio element, but then what do I do with silent videos?

Also the seeking property should work, but it doesn't

phone-inline-video with Meteor?

Do you have any experience using this in a Meteor application?

I'm trying to integrate it, but having a few issues getting it to work. This is EXACTLY what I need. After hours of searching why webkit-playsinline didn't work, this is my last hope.

thanks!

Possible to do seek?

First of all, it works great! Audio could shift playback a little forward to make a tighter sync, but otherwise, it's great! Wondering whether you can implement currentTime seek. I know the demo code has comments that the user cannot set this. Is there a way round to do this?

Add bower

Would be pretty cool if we could add bower to this rep (useful for things like Ionic).

Add unit tests

For two reasons:

  • stability, no doubt
  • reported two unknown bugs recently, because there are no unit tests for nodejs environments alone

Proxy more properties

Perhaps I could do a blanket search-and-proxy with Object.keys() but this only works when it's not muted

ReferenceError: window is not defined

var _Symbol = window.Symbol || function (description) {
              ^

ReferenceError: window is not defined
    at Object.<anonymous> (/home/michael-heuberger/binarykitchen/code/videomail-client/node_modules/iphone-inline-video/dist/iphone-inline-video.common-js.js:70:15)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Module.require (module.js:353:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (/home/michael-heuberger/binarykitchen/code/videomail-client/src/wrappers/visuals/replay.js:3:31)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)

Happens when I run local unit tests with tape test/**/*.test.js

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.