I am having an issue with Video streaming on vlc plugin in Windows safari. I have added windowless="true" attribute in embed tag so that I can display transparent DIV above vlc plug in for Drawing on video. After adding this tag video is stopped and video frame is not received. But When I click on video or draw something on video, video frame refreshed for a while. Even if when I remove windowless="true" attribute video works.
Issue is observed in windows safari only with windowless="true".
I have the exactly same behavior. Windows 10, Safari 5.1.7.
So far the only solution I found is a workaround to force browser updating the player's frame. I do it by quickly adding and removing a "glass" div: a region that occupies whole browser's screen and has an opaque background fill color. Since it's transparent there is no any visible changes on the screen but Safari always redraws overlapped regions even if they are overlapped by a transparent pane. Here is what I do:
function play() {
// ...create player, set properties, etc.
// assuming player taking whole browser's screen.
// It's a glass pane - it should cover whole player's output surface.
var glass = $('<div>');
$('body').append(glass);
// Here we start updating...
setInterval(function() {
$('body').toggleClass('glass');
}, 20); // <== 1000ms / 30fps = 33ms, put 20ms just in case.
}
.glass {
position: absolute;
width: 100%;
height: 100%;
z-index: 10000;
background-color: rgba(40,1,1,0);
}
Of course, you need to adjust z-index so what glass is overlapping player surface but not blocking your custom controls.
Yes, it's an ugly hack but it works as a short term solution.
Related
As I'm playing with WebRTC in Chrome, I'm noticing that the durability of these streams is still somewhat shaky. I need to create a video stream before the element displaying it is shown (technically I only need the audio track initially, but renegotiation without replaceTrack() seems to be an issue all in its own, so I'm enabling both at once for now).
The element is then rendered dynamically by JavaScript and needs to start receiving WebRTC video. The problem is that at the time of WebRTC creation this video element where I want to show it does not yet exist. I don't see a way to tell WebRTC to change the video element being rendered to after the stream starts, is that possible? I was mainly playing with SimpleWebRTC, but am open to using WebRTC directly - from looking at the docs I couldn't find a way to do it with raw WebRTC either. I also tried moving the original video element into the new element, but this causes the video stream to break/stop:
newElement.appendChild(originalWebRTCVideoTag);
Short of killing the entire stream and restarting, what are my options?
UPDATE:
For both approaches, videoTag is a generic DOM video tag, webrtc is an instance of WebRTC object with a working connection established via SimpleWebRTC (simpleWebRtc.webrtc, which SimpleWebRTC wraps around). I'm putting together a JSFiddle right now for those who want to see the actual code but this should be enough information to reproduce this.
// this doesn't seem to be working in stackoverflow, probably because it rejects video camera capture
var simplertc = new SimpleWebRTC({
localVideoEl: 'webrtc-local',
remoteVideosEl: 'webrtc-remote',
media: {"audio": true, "video": {
"optional": [{"minWidth": "640"}, {"minHeight": "480"}], "mandatory": {}
}},
autoRequestMedia: true
});
var webrtc = simplertc.webrtc;
// this portion is overly simplified, in this case there is no point
// in creating this dynamically, in the app I'm working on this element
// is generated much later
$('#dynamic').appendTo('<video id="dynamic-video"></video>');
var videoTag = $('#dynamic-video')[0];
simplertc.on('readyToCall', function() {
simplertc.joinRoom('my-room-875385864'); // random name
// by this time the local video should be ready, we don't need remote ones for our test
// test case 1 (replace with logic from test case 2 if needed)
videoTag.srcObject = webrtc.localStreams[0];
// end test case
});
video {
border: 1px solid red;
width: 200px;
}
/* overlap with original video is intentional to show hardware acceleration effect */
#dynamic {
position: absolute;
border: 1px solid black;
width: 200px;
height: 200px;
left: 100px;
top:50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="https://simplewebrtc.com/latest-v2.js"></script>
<div id='webrtc'>
<video id='webrtc-local'></video>
<div id='webrtc-remote'></div>
</div>
<div id='dynamic'>
</div>
Approach 1, stumbled upon this by accident while attempting approach 2
Tried the following, it works but much slower than I'd like, about 5 FPS:
// note that I can just as easily use remote streams here
videoTag.srcObject = webrtc.localStreams[0]
Ironically, while messing with this approach more I accidentally overlapped the video regions of the webRTC element and the one generated (videoTag), and even though webRTC is on the background, that corner of videoTag where it overlaps does run in real time, unlike the rest of the element which continues running at 3-5 FPS. This is leading me to believe that the issue here is hardware acceleration. Can I enable it for the videoTag somehow?
Approach 2
var media = new MediaSource();
videoTag.src = URL.createObjectURL(media);
// guessing mimetype from a few WebRTC tutorials I stumbled upon
var srcBuf = media.addSourceBuffer(‘video/webm;codecs=”vp8, vorbis”’);
// need to convert webrtc.localStreams[0] or its video track to a buffer somehow???
srcBuf.appendBuffer(/* buffer */);
FURTHER RESEARCH
This may be a bug in Chrome, a hackerish workaround that seems to work is to make sure the newly generated video elements are completely overlapped by the original video element (even if the original video element is set to render on the background behind all other elements (and behind a non-transparent background). This seems to kick in hardware acceleration.
You can use MediaSource, sourceopen event, .addSourceBuffer(), .appendBuffer(). See HTML5 audio streaming: precisely measure latency?, Unable to stream video over a websocket to Firefox
I am building an app that requires a full page background image. I am using Angular JS and CSS3 for the background image.
On page load, the <body back-img> custom directive is hit and runs the following code:
var grindModule = angular.module('grindApp', ['ngRoute'])
grindModule.directive('backImg', function(){
return function(scope, element, attrs){
var url = ['./../static/images/pushup.jpg', './../static/images/work.jpg']
var idx = Math.floor(Math.random() * url.length)
element.css({
'background': 'url(' + url[idx] +') no-repeat center center fixed',
'background-size' : 'cover'
});
};
A random index is generated and then is used to get a random image url from the array that stores them. It then places said url in the following piece of codebackground: url().
Once the page loads the page looks like this:
Notice the black white space at the bottom of the screenshot. I don't want this. This background is working on all devices except this particular phone (that I know of). This bug is only generated when I am using the mobile version of the Chrome browser. It does not happen when I use the mobile Firefox browser. Seems to be Chrome specific, but I could be very wrong.
Here is all of my code if you feel like that could help you: Grind Github.
I had a look at your website.
This is my train of thought:
1) The browser on that mobile could be outdated and is not supporting the "cover" property correctly. But the issue with this is that you've added "center center" as the background position, so, at the worst, the browser -should- be displaying that image aligned at the center of the page by it's center at full scale, which it is not.
2) The fact that the image is not even centered, makes me think that the "body" element is somehow not functioning properly with a height set at 100%. Try adding height 100% to your HTML tag as well.
html,body {
height: 100%;
}
3) If #2 didn't fix it, then I would try and add another element into the page, just after the starting <body> tag like this:
<div class="bg-fullpage-wrapper"></div>
The style for this element should be:
div.bg-fullpage-wrapper {
/* Your current background stuff here ie:
background: url("./../static/images/work.jpg") 50% 50% / cover no-repeat fixed;
*/
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
Remove the height 100% from body tag for this attempt. You'll have to fix z-index of elements when you do it like this.
4) If this DIV doesn't make it work, then I would probably start thinking in terms of browser resources running out etc since the images that seem to load up for me are massive for web format, there might be issues with downscaling from/to that resolution.
This is a CSS issue, not a JS issue. Outside of that, however, I have no idea what's going on behind the scenes.
head {min-height: 100%}
That's all I know.
Reproduced on an Xperia Z2 with Chrome https://developers.google.com/web/tools/chrome-devtools/debug/remote-debugging/remote-debugging
I'm using the BigVideo.js plugin (http://dfcb.github.io/BigVideo.js/) in a website of mine. I am also using the following Javascript to scale the site up or down as the user resizes their browser.
$(document).ready(function() {
scaleSite();
});
$( window ).resize(function() {
scaleSite();
});
// Scale Site to Fit Window
function scaleSite() {
var windowWidth = $( window ).width();
var defaultWidth = 1200;
var scaleWidth = 1;
var isMobile = false;
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
// MOBILE ACTIONS
} else {
// STANDARD ACTIONS
if(windowWidth >= defaultWidth) {
scaleWidth = windowWidth/defaultWidth;
var scaleWidthRounded = Math.round( scaleWidth * 10 ) / 10;
} else {
scaleWidth = windowWidth/defaultWidth;
var scaleWidthRounded = Math.round( scaleWidth * 10 ) / 10;
}
$("#mainDiv").css("-webkit-transform", "scale("+scaleWidth+")");
$("#mainDiv").css("-moz-transform", "scale("+scaleWidth+")");
$("#mainDiv").css("-o-transform", "scale("+scaleWidth+")");
$("#mainDiv").css("msTransform", "scale("+scaleWidth+")");
$("#fixedHeader").css("-webkit-transform", "scale("+scaleWidth+")");
$("#fixedHeader").css("-moz-transform", "scale("+scaleWidth+")");
$("#fixedHeader").css("-o-transform", "scale("+scaleWidth+")");
$("#fixedHeader").css("msTransform", "scale("+scaleWidth+")");
// RESET BODY HEIGHT
var mainDivHeight = ($("#mainDiv").height()*scaleWidthRounded);
$("body").css("height", mainDivHeight);
$("html").css("height", mainDivHeight);
}
}
Strangely enough, when I load a page that has a video playing on it, and I try to resize the browser, the scaling works correctly but everything BUT the video gets a little blurred.
I had trouble with this same issue when using the Jssor Slider plugin, it also caused my pages to blur after resizing the browser window. I resolved that issue by adding the $HWA : false to the options for the Jssor Slider, which disabled the plugins ability to use Hardware Acceleration.
Is there something in the BigVideo.js or the underlying Video.js file that I can adjust to prevent hardware acceleration there as well? As it seems to be the same cause.
UPDATE
I just noticed the blur issue ONLY happens in Chrome. Firefox and Internet Explorer both work fine with no problem, but in Chrome, all content on the page OTHER than the BigVideo itself gets slightly blurred.
UPDATE 2
Okay, so I just noticed that if I inspect element on the div containing the HTML5 <video> tag and I delete it from the DOM, my text "snaps" back into focus. I went through the div item by item and unchecked CSS styles thinking that would lead me to the one that is causing problems but still no luck.
Why would deleting the element from the DOM in the Chrome DEV tools snap the rest of the page back into focus and remove the blur?
Below is a screen shot showing an example of the text on my page BEFORE I resize the browser window, and the result AFTER I resize. Again, if I resize, the page gets a bit blurry, and if I delete the element containing the <video> using the Chrome DEV tools, the blur goes away.
UPDATE 3
So I removed the BigVideo plugin and replaced it with a generic HTML5 <video> tag, the video still plays and the blur issue is still present when resizing the browser. So it's something with the way chrome is handling the HTML5 video along with my scale site script.
JSFIDDLE
https://jsfiddle.net/h5vu7La7/3/
Not sure if this will help or not, but if you resize the window on this jsFiddle you can see the text (in Chrome) is blurred a bit. If you remove the <video> from the HTML and re-run and resize it does not blur.
Also noticed if you run the fiddle, and inspect element on the video and delete it from the DOM, the text snaps back into focus.
If you are applying transform scale CSS rule to a HTML element that has child elements (I'm guessing those visible in the pictures are inside one of the divs you are scaling), they will get somewhat blurry due the layer moving to 3D plane.
Open inspector and apply transform: scale(1.01); to the blue button below here on SO and you'll realize what I mean.
Instead of scale, you should just resize the width and height of the video element.
I need to add a overlay of rectangular shape to an object (eg. water bottle) in my html5 video, and then track the object throughout the video.
I already have a txt file which contains the object's positions for each frame throughout the video. So I need to:
draw the rectangular shape on each frame of the html5 video. so when the video is being played, we can see the tracking box moving with the object
the tracking box's movement should be synchronised with the video. so when the user click 'pause', the tracking will pause too.
I just need some general advice on how to approach this problem. Is there javascript package that can draw shapes on videos?
1) With HTML5 video, you can't tell what 'frame' the video is on. Only what the current position is in the video in seconds (i.e. 5.4423 seconds, it can be quite specific). If you know how many frames per second your video has (and it's constant) you can reasonably estimate what frame you are on by multiplying frames by current seconds. Simply use videoElement.currentTime to get the elapsed playback time.
To get the current seconds data throughout playback, use the setInterval function and run it every 40 milliseconds (assuming you have a 25 fps video)
2) In you setInterval callback grab the relevant box position from your data file (based on the elapsed seconds/frames) and update the x and y position of the box using javascript (e.g. element.style.left = x + "px"
The box will stop on pause because the elapsed seconds will stop too. Hint: make the box position absolute and the element containing the video position relative, and the box will move relative to the top left corner of the video.
Hope that helps!
Edit: lay out your html like this:
<div id="videoContainer">
<div id="box"></div>
<video id="videoElement" controls>
<source src="myVideo.mp4 type="video/mp4" />
</video>
</div>
And your CSS:
#videoContainer {
position: relative;
}
#box {
width: 100px;
height: 50px;
background: red;
position: absolute;
left: 0;
top: 0;
}
I found this html5 video player which supports youtube source. But it didn't have a fullscreen button, so I started to implement the full screen function.
My problem now is that on chrome or safari the video doesn't take 100% width (not really fullsize, i have a black gap on all sides).
I used this script:
$('.video-fullscreen-btn', player).bind('click', function(e){
if (player.requestFullscreen) {
player.requestFullscreen();
} else if (player.msRequestFullscreen) {
player.msRequestFullscreen();
} else if (player.mozRequestFullScreen) {
player.mozRequestFullScreen();
} else if (player.webkitRequestFullscreen) {
player.webkitRequestFullscreen();
}
});
I also tried it with the css webkit
:-webkit-full-screen video {width: 100%; height: 100%;}
still not working. does someone have an idea why this is not working on chrome/safari?
The whole example can be found here: http://jsfiddle.net/Z5PTv/
I think it is just due to the aspect ratio of the actual video content. If you look at the original youtube video it also has black bars either side of the video.
That is why the preload image looks pixelated because the image, which has the same aspect ratio as the video I assume, has been forced to take up the space.
If the video was to be the full width of the screen the top and bottom of the video would be clipped off. I assume you would rather have black bars on the side rather than clipping.
If the problem is aspect ratio you can control is with CSS object-fit: fill;
But this is only supported in Opera right now.
If the video element is using 100% of the screen this doesn't mean that the video-image it self will be stretched to fill the whole screen. You can opserve this by using the controls attribute on the video element and notice how the controls can be wider then the video-image.
Demo : http://netkoder.dk/netkoder/eksempler/eksempel0017.html