Cordova playing html5 video - javascript

I use cordova to build a hybrid signage application. I need to display a video on part of the screen when I try to display it then I don't see any video but sound. When I display video as fullscreen there is no problem. But I need to display it on part of the screen for example width: 400px height:400px top:100px left:100px
<video
id="videoContent_0" src="file:///storage/emulated/0/DS/MediaFiles/1004.mp4" autoplay="" style="z-index: 100; display: inline-block;">
</video>

Better solution to use cordova plugin then you can achieve wanted result.
Installation
cordova plugin add com.moust.cordova.videoplayer
Using: Just call the play method with a video file path as argument. The video player will close itself when the video will be completed.
VideoPlayer.play(
"file:///android_asset/www/movie.mp4",
{
volume: 0.5,
scalingMode: VideoPlayer.SCALING_MODE.SCALE_TO_FIT_WITH_CROPPING
},
function () {
console.log("video completed");
},
function (err) {
console.log(err);
}
);

Related

ReactJS canvas drawImage without showing html5 video element

I need to draw the stream from camera on top of a canvas using drawImage, however when I add the video element in react component it shows the element's stream in the page too. If I use display:'none' drawImage can't draw the user's webcam, it draws blank screen. Do I have to show html5 video element in the page or is there a way to play it without showing?
I am getting video stream from camera with getUserMedia:
async function getCameraStream() {
try {
const constraint = { video: true }
const stream = await navigator.mediaDevices.getUserMedia(constraint)
if (videoRef.current) {
videoRef.current.srcObject = stream
return
}
} catch (error) {
console.error('Error opening video camera.', error)
}
setLoading(false)
setCameraError(true)
}
And the video ref is:
return( <video
style={{display: 'none' }}
ref={videoRef}
className={classes.sourcePlayback}
src={sourceUrl}
hidden={isLoading}
autoPlay
playsInline
controls={false}
muted
loop
onLoadedData={handleVideoLoad}
/>)
I am using this videoRef in canvas like:
ctx.drawImage(sourcePlayback.htmlElement, 0, 0)
Here if the htmlElement is given with display:'none' it doesn't draw. I want to draw the htmlElement but not show it in the page.Is there a way to achieve this? I want html5VideoElement to play invisibly basically.display:none does not work.
EDIT:
Add css as visibility:'hidden' works for this one.
sourcePlayback: {
visibility: 'hidden',
display: 'flex',
width: 0,
height: 0,
},
I was able to replicate your issue in chrome with https://record.a.video.
When I used display: none on the video attribute, the video overlay on the canvas was black instead of my camera.
Workaround:
When I set the CSS on the video to width:1px, the video shows up on the canvas. I suppose it's technically on the screen, but it'll probably work for your purposes.

Youtube embed autoplay on mobile

I use React to set iframe with youtube video on page in correct size. All works well but for mobiles doesn't work autoplay option.
What is interesting for page, what I have as example video it works perfect.
<iframe type="text/html" allowTransparency="true" height="100%" width="100%" preload="metadata" gesture="media" allow="encrypted-media" className="autoplay-iframe"
src={`https://www.youtube.com/embed/`+this.props.autoplay+`?autoplay=1&version=3&html5=1&hd=1&controls=0&loop=1&playlist=`+this.props.autoplay+`&playsinline=1&rel=0&showinfo=0&modestbranding=1&related=0&enablejsapi=1&origin=`+window.location.hostname} frameborder="0"></iframe>
above is my iframe code.
I cut some part of iframe code but there are just style in styles attribute. It isn't important for autoplay.
The same finally url for other page works. I'm not sure why. Any hints how I can solve this problem?
Thanks in advance.
You will not be able to implement this, since it is intentionally disabled to all mobile devices. The reason is for the user to save cellular data. It is also cited in this post.
The reason that video autoplay doesn’t work is simple. The feature is
deliberately disabled in both iOS and Android for mobile devices.
The reason this is done is to save mobile users money. Such devices
(especially mobile phones) often use data connections that charge by
bandwidth. They have data limits and going over results in a fee.
This statement was also supported with the following SO post.
no autoplay in iframe HTML5 player on mobile (Android Chrome and Firefox)?
how to get embedded youtube video to autostart on iphone
Youtube autoplay not working on mobile devices with embedded HTML5 player
I was able to get Youtube videos to play (without muting them). Because loading Youtube videos inline was upsetting Google and their new Core Web Vitals, we implemented a thumbnail placeholder that when clicked (jQuery) initiates loading the video using the Youtube Iframe API. I too could not get them to autoplay at first. The issue was resolved by having the API embed the Iframe--not putting the iframe in place before hand. It autoplays on iOS Safari, Chrome and Firefox. Here's what worked for me:
On document ready:
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
function onYouTubeIframeAPIReady(yt_id, iframe_id, iframe_width, iframe_height){
player = new YT.Player(iframe_id, {
width: iframe_width,
height: iframe_height,
videoId: yt_id,
playerVars: { 'autoplay': 1, 'playsinline': 1 },
events: {
'onReady': onPlayerReady
}
});
}
function onPlayerReady(event) {
//event.target.mute();
event.target.setVolume(70);
event.target.playVideo();
}
on click event:
$('.yt_video_link').on('click', function(e) {
e.preventDefault();
var div_id = $(this).attr('id');
var div_iframe = div_id + '_iframe';
var yt_id = $('#' + div_id).data('ytid');
$('#' + div_id + ' .yt_video_play').css('display', 'none');
onYouTubeIframeAPIReady(yt_id, div_iframe, 560, 315);
});
HTML:
<div id='yt_video_desktop' class='yt_video_link mobile_hide' data-ytid='<?=$yt_id?>'>
<div id='yt_video_desktop_player' class='yt_video'>
<img src='/catalog/images/yt_video_thumb_<?=$yt_id?>.jpg' alt='play desktop video' width='768' height='432' id='yt_video_desktop_iframe'>
</div>
<div class='yt_video_play'></div>
</div>
Google official statement "Due to this restriction, functions and parameters such as autoplay, playVideo(), loadVideoById() won't work in all mobile environments.
Reference: https://developers.google.com/youtube/iframe_api_reference
By adding the parameter playsinline: 1 I managed to make the autoplay work on android and ios.
createYoutubePlayer() {
this.youtubePlayer = new YT.Player('youtubePlayer', {
videoId: 'YOURID', // YouTube Video ID
width: 277, // Player width (in px)
height: 600, // Player height (in px)
playerVars: {
autoplay: 1, // Auto-play the video on load
controls: 0, // Show pause/play buttons in player
showinfo: 1, // Hide the video title
modestbranding: 1, // Hide the Youtube Logo
loop: 1, // Run the video in a loop
fs: 0, // Hide the full screen button
cc_load_policy: 0, // Hide closed captions
iv_load_policy: 3, // Hide the Video Annotations
autohide: 1, // Hide video controls when playing
playsinline: 1, //forbid fullscreen on ios
},
events: {
onReady: (e) => {
e.target.mute();
},
onStateChange: (e) => {this.onPlayerStateChange(e)}
}
});
}
The rules have changed so most new mobiles will now let you autoplay, but most video streaming sites like youtube and vimeo haven't enabled the functionality yet. The reason the html5 video worked but the iframe didn't is because youtube disabled it.
For anyone dealing with this on react native, you can override the user agent and it works like a charm:
<WebView
userAgent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
...
The reason that video autoplay doesn't work is simple. The feature is deliberately disabled in both iOS and Android for mobile devices. The reason this is done is to save mobile users money. Such devices (especially mobile phones) often use data connections that charge by bandwidth.

Extending video frame to full-screen from jPlayer using onClick function

functionality:
User is able to access the video page from the main menu. Video will be played automatically, at this moment, the video is not in full screen and for aesthetic purposes, there are no control buttons in the video frame.
Secondly, when user clicks on the video, it will be displayed as full-screen, and when user clicks on the full-screen video, the video will exit the full screen and reverts back to the original video frame size.
What has been done:
I have created the video frame by using the jQuery .jPlayer. And the video is playing automatically when the video page is loaded.
I have attached the following code:
function Footprints() {
console.log("Footprints");
//Main video player for video page
$("#Footprints_1").jPlayer({
ready: function() {},
swfPath: "javascript",
supplied: "webmv, ogv, m4v",
loop: true,
size: {
width: 1450,
height: 750
}
}).bind($.jPlayer.event.play, function() { // pause other instances of player when current one play
$(this).jPlayer("pauseOthers");
});
$("#Footprints_1").jPlayer("setMedia", {
//set m4v tag to array Footprints VideoList
m4v: "http://www.jplayer.org/video/m4v/Finding_Nemo_Teaser.m4v"
}).jPlayer("play");
$("#Footprints_1").show();
$("Footprints_1").click(function() {
console.log("fullscreen")
$("#Footprints_1").requestFullscreen();
})
}
<div id="Footprints_Page" align="center" style="position:absolute; background-repeat: no-repeat; display: none; top:0px; left:0px; ">
<!--Video Player-->
<div id="Footprints_1" style="position:absolute; top: 180px;"></div>
</div>
Hence, when you run the code, it is showing this:
Issue:
At this point, when I click on the video frame when the video is playing, nothing happens. The video doesn't expand to the full screen.
Hence, how am I able to make the video expand to full screen when I click on the video and and when the video is clicked it reverts back to the original size.
Thanks.
You are currently fighting two three issues.
The first is you are not using jplayer's event system. that is why the clicks are being ignored.
I added a bind.click to your jplayer decleration, and the clicks responded.
.bind($.jPlayer.event.click, function() {
console.log("fullscreen")
$("#Footprints_1").requestFullscreen();
});
See this Fiddle.
The second issue is that you are calling requestFullscreen() on a jQuery object. It is not part of the jQuery API. You need to be calling it on an HTML element.
document.getElementById("jp_video_0").requestFullscreen();
So, the above example should probably be: (untested)
.bind($.jPlayer.event.click, function() {
console.log("fullscreen")
document.getElementById("jp_video_0").requestFullscreen();
});
If you want to have some control over padding and placement, request fullscreen on the container, and you can use CSS.
document.getElementById("Footprints_1").requestFullscreen();
However, the third issue is that not all browsers seem to use the same method of requestFullscreen(). See Mozilla docs. For me the following worked in Chrome:
.bind($.jPlayer.event.click, function() {
console.log("fullscreen")
var elem = document.getElementById("Footprints_1");
if (elem.requestFullscreen) {
elem.requestFullscreen();
} else if (elem.msRequestFullscreen) {
elem.msRequestFullscreen();
} else if (elem.mozRequestFullScreen) {
elem.mozRequestFullScreen();
} else if (elem.webkitRequestFullscreen) {
elem.webkitRequestFullscreen();
}
})
This Post has more info on fullscreen from jQuery as well as info on x-browser issues.
Hope it helps.
Edit: jsFiddle can't demonstrate the Fullscreen API, because I can not add the required 'AllowFullscreen' attribute to their iframe. If you view the frame source of the jsFiddle result, you can just save that as an HTML document, and it should work.

Hide (not remove) HTML5 video controls

Every question on the subject explain how to remove the controls of an HTML5 video element.
videoElement.removeAttribute('controls');
But browsers, Firefox and Chrome, have a way of just hiding the controls which makes them disappear when cursor is not moving and the video is playing. And makes them appear again if you move the cursor or when video stops playing.
<video controls><source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
Video test file: http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4
If you play the above video, and leave it alone without moving the cursor, the controls will disappear. The if you move the cursor again they'll appear again. They'll also appear upon pausing or video finishing.
Very much like popular native or desktop video players.
This is what I want. I want to hide the controls the same way they would automatically hide if the video were playing and the cursor hasn't moved for a while.
Is there a way to achieve this without removing the controls entirely?
Try this:
$("#myvideo").hover(function() {
$(this).prop("controls", true);
}, function() {
$(this).prop("controls", false);
});
// if always hide
$("#myvideo2").click(function() {
if( this.paused)
this.play();
else
this.pause();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<video id="myvideo" width="200" >
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4">
</video>
<br/>All time hide controls:<br/>
<video id="myvideo2" autoplay width="200" >
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4">
</video>
Put a div over the video and hide/show that, you answered your own question;
I want to hide the controls the same way they would automatically hide if the video were playing and the cursor hasn't moved for a while.
Also take a look at this;
Styling HTML5 Video Controls
I'm using videojs.com library and the solution was to add
.vjs-control-bar {
display:none !important;
}
to the stylesheet.
You can set event listener on your video and remove controls on play
<video id="video">
<source src="http://example.com/video.mp4" type="video/mp4"/>
</video>
<script>
video.addEventListener('play', () => {
video.setAttribute('controls', 'true');
});
video.addEventListener('pause', () => {
video.removeAttribute('controls')
});
</script>
use this:
video::-webkit-media-controls {
display: none;
}
you don't need javascript. use CSS.
Display:none on the controls.

How to add loader image to HTML5 video?

Along with the poster image I want a loader image(an animated gif) to be displayed while the video is being downloaded. How is it possible ?
A cheap way could be to use an animated GIF in the poster attribute which will be replaced when the video begins to play. Example:
<video poster="loading.gif" preload="auto" controls autoplay>
<source type="video/mp4" src="video.mp4"/>
</video>
Here is my solution for this problem since pixelearth's answer doesn't seem to work on firefox (probably a problem with the fake poster)
HTML
<video id="video1" height="236" preload="auto" controls>
<source src="yourVideo.mp4">
Your browser does not support HTML5 video.
</video>
JS
$('#video1').on('loadstart', function (event) {
$(this).addClass('background');
$(this).attr("poster", "/your/loading.gif");
});
$('#video1').on('canplay', function (event) {
$(this).removeClass('background');
$(this).removeAttr("poster");
});
CSS
video.background {
background: black
}
With this answer you don't have to mess around with fake poster or abuse attributes for purposes that they were not made for. Hope this helps.
P.S. You could of course add some more events to add the poster attribute e.g. if it can't play further in the middle of the video and needs more buffering
You can find a jsfiddle which shows my code here
It took me a way too long to actually figure out how to do this, but I'm going to share it here because I FINALLY found a way! Which is ridiculous when you think about it, because loading is something that all videos have to do. You'd think they would have taken this into account when creating the html5 video standard.
My original theory that I thought should have worked (but wouldn't) was this
Add loading bg image to video when loading via js and css
Remove when ready to play
Simple, right? The problem was that I couldn't get the background image to show when the source elements were set, or the video.src attribute was set. The final stroke of genius/luck was to find out (through experimentation) that the background-image will not disappear if the poster is set to something. I'm using a fake poster image, but I imagine it would work as well with a transparent 1x1 image (but why worry about having another image). So this makes this probably a kind of hack, but it works and I don't have to add extra markup to my code, which means it will work across all my projects using html5 video.
HTML
<video controls="" poster="data:image/gif,AAAA">
<source src="yourvid.mp4"
</video>
CSS (loading class applied to video with JS)
video.loading {
background: black url(/images/loader.gif) center center no-repeat;
}
JS
$('#video_id').on('loadstart', function (event) {
$(this).addClass('loading')
});
$('#video_id').on('canplay', function (event) {
$(this).removeClass('loading')
});
This works perfectly for me but only tested in chrome and safari on mac. Let me know if anyone finds bugs and or improvements!
You could attach a listener to the video's loadstart event and use it to overlay an animated GIF on top of the video element, then hide the loading overlay once the loadeddata event fires. See The W3C's media events draft for a list of events you can hook into.
They also have a demo page for media events.
This is quite complicated, you must listen to various video events to show/hide & update width of the loader image correctly. Those events include (but may not limited to): loadstart, progress, loadeddata, waiting, seeking, seeked. You can use a certain open source player (e.g. jPlayer) or download its source to examine further.
<video
id="mainVideo"
width="100%"
style="max-width: 100%; max-height: 100%;"
preload="auto"
autoplay="autoplay"
(loadeddata)= "checkVideoLoaded()"
>
<source [src]="assets?.video?.urlMP4" type="{{videoType}}">
</video>
on isVideoLoaded flag show and hide loader
this.isVideoLoaded = false;
checkVideoLoaded(){
this.isVideoLoaded = true;
}

Categories