HTML5 Canvas - Mirror parts of video - html

I've found a really awesome slider on a website (https://antoni.de)
The slider has videos set as backgrounds and the transition effect makes the video break into pieces (bars, varying in width, depending on the scrollpos)
How could I achieve a relatively close version of this?
Here's my current code:
HTML + jQuery:
<div id="slider">
<canvas id="c" width='1920px' height='1080px'></canvas>
<video id="v" preload="auto" autoplay="" loop="" muted="">
<source src="common/vid/stage_loop.mp4">
</video>
</div>
<script>
// Copy video to canvas
document.addEventListener('DOMContentLoaded', function(){
var v = document.getElementById('v');
var canvas = document.getElementById('c');
var context = canvas.getContext('2d');
v.addEventListener('play', function(){
draw(this,context,canvas.width,canvas.height);
},false);
},false);
function draw(v,c,w,h) {
if(v.paused || v.ended) return false;
c.drawImage(v,0,0,w,h);
setTimeout(draw,20,v,c,w,h);
}
</script>
Css:
#slider {
display: block;
width: 100%;
height: 100vh;
background-color: black;
overflow: hidden;
position: relative;
}
#slider canvas {
position: absolute;
top: 50%;
left: 50%;
z-index: 1;
min-width: 1920px;
min-height: 1080px;
width: auto;
height: auto;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
#slider video {
position: absolute;
width: 20px;
height: 20px;
opacity: 0;
}
What could I do?:/
I've found nothing related online, I'm a beginner using html canvases

You will need to draw the video onto one canvas, then draw the fragments (in any order you choose) from that canvas onto a second canvas, which will be what's displayed.
This is how all video manipulation is done, for example this (somewhat famous and old) "explosion" example using video and mapping it to the canvas:
http://www.craftymind.com/blowing-up-html5-video-and-mapping-it-into-3d-space/

Have a look at the drawImage() documentation on MDN. You can scale and position the video for each frame by adjusting the source and destination parameters in drawImage(). For example, to draw a 20 pixel vertical stripe of video to the far right of the canvas, you would do this:
ctx.drawImage(
v, // video frame
0,0,20,h, // source: x=0, width 20
w-20,0,20,h // destination: x=(w-20), width 20
);
Adjust the x value in the destination will slide around the vertical stripes. Adjusting the x value in source will slide around the video. If you set the widths differently the canvas will stretch and scale.
Also you should be using requestAnimationFrame (rAF) instead of setTimeout. rAF let's the browser have more control over when to draw the image, freeing up resources and resulting in really smooth animations. The only time you would want to use setTimeout is if you were very particular about frame rate (how fast things animate) but even then there are ways to throttle rAF. Ideally you want 60 frames per second. rAF will aim for that and start to slow down if there is too much processing during each frame.

Related

autoplay not working when browser zoom is above 75%

more or less a complete noob here, so apologies in advance if this question is completely ridiculous!
Effectively I'm building a one page site (artistic purposes) - contained on this site is a video-bg set to autoplay. The autoplay function works fine across all browsers (minus IE) and all devices I've tested thus far.
There's just one issue...
For reasons inexplicable to this noob, autoplay only works when the browsers inbuilt zoom is set to 75% or below. Just to double check this, I trialled embedding the video with 'controls'. Still, the outcome was the same, the video autoplays when the browser zoom is set to 75% or less and it would only play above 75% when prompted ('play' control was clicked) by the user/viewer.
For reasons I can't figure out, autoplay (in my case) is being effected by browser zoom??
I'm working in Muse... Most likely a faux pas??
HTML:
<div class="video-container">
<video autoplay muted loop id="video-bg">
<source src="assets/maskon.mp4" type="video/mp4">
Your browser does not support HTML5 video. Please update to view video content :)
</video>
</div>
CSS:
<style>
#video-bg {
position: relative;
min-width: 100%;
height: 100vh;
}
.video-container {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
min-height: 100%;
min-width: 100%;
}
</style>
Further apologies for using wrong code insertion function... Code Sample was previewing with about half of code missing??
Your code works in Firefox correctly !
This is probabely one of WebKit's bugs of html5 video
you should use .play() function of javascript to autoplay !
as links below :
Video auto play is not working in Safari and Chrome desktop browser
add this code just after the </video>
<script>
document.getElementById('vid').play();
</script>
UPDATED - TEMPORARY SOLUTION
Thanks to #kaiido I found a temporary solution to this problem.
Inserting the code: window.onresize = function() { requestAnimationFrame(function() { document.getElementById("video-bg").play();})}; after </video> has allowed for functional autoplay capabilites at all zoom resolutions.
Still a bit buggy (page needs to be reloaded every so often) when zooming up/down however, a good for workaround for now :-)

HTML5 Video Fallback Image Issue Loading Messy

I have a fallback poster image inside my html5 video preload settings that loads messy while waiting for the actual video to load as it sits then suddenly disappears when the video loads. My question is can I code this transition more neatly and how can I not make the image flash then disappear so messy just right before the video loads? Also when video cannot be loaded such as on mobile/and handheld devices how to remove the play button rendered to the fallback image?
Here are my settings:
<div class = "sudirlayheader-container">
<div class = "sudirlayvideo-container">
<video preload = "auto" autoplay = "autoplay" loop = "loop" volume = "0" poster="video/Dubai-Wallpaper.png">
<source src = "video/sudirlayvid.mp4" type = "video/mp4">
<source src = "video/sudirlayvid.ogg" type = "video/ogg">
<source src = "video/sudirlayvid.webm" type = "video/webm">
<source src = "video/sudirlayvid.mov" type = "video/mov">
</video>
</div>
</div>
I found my own solution, apparently the html5 code that I originally have is correct and the best way to do things but the way to make a smooth transition is mainly just a little editing of css and picture schemes on my behalf. So sum it up I just took a snapshot of the main pic and lightened the frame so that if the video loads but takes time the fallback image just seems to be a cool fade in effect and the css is used to remove the play button when the video does not load on mobile/and handheld devices etc.
Now my main css looks like this:
.header-container {
width: 100%;
height: 900px;
border-left: none;
border-right: none;
position: relative;
padding: 20px;
}
.video-container {
position: absolute;
top: 0%;
left: 0%;
height: 100%;
width: 100%;
overflow: hidden;
}
video {
position: absolute;
z-index: -1;
opacity: 1;
width: 100%;
}
Notice this line fixes the weird button showing up on the fallback image when video doesnt load
video::-webkit-media-controls-start-playback-button {
display: none;
}

video with equal width and height [duplicate]

Is there a way I can cut off the corners of my html5 video element using the CSS3 border-radius attribute?
Check out this example. it's not working.
Create a div container with rounded corners and overflow:hidden. Then place the video in it.
<style>
.video-mask{
width: 350px;
border-radius: 10px;
overflow: hidden;
}
</style>
<div class="video-mask">
<video></video>
</div>
We have a video playing with rounded corners and a drop shadow and it's as simple as:
border-radius: 22px;
overflow: hidden;
-webkit-transform: translateZ(0);
box-shadow: 0 19px 51px 0 rgba(0,0,0,0.16), 0 14px 19px 0 rgba(0,0,0,0.07);
The key is the -webkit-transform: translateZ(0). This line of code tells the browser to render on the GPU instead of with the
Tested and working as of Safari 11, Chrome 65, Firefox 59, Edge Win 10 & IE 11
It works in Firefox as long as you set the appropriate 180px height for the 320px width video (16:9 aspect ratio) - otherwise the curved borders aren't visible because they're outside the frame of the video.
There are some outstanding bugs in WebKit to do with it clipping content in concert with border-radius, like this one or this one specifically about the video element.
Unfortunately, Chrome and Safari do not support border-radius on <video> elements.
If all of your videos are the same size, you could use a CSS mask with an SVG file. If your videos are dynamically sized, that makes things more difficult...
(edit: the SVG mask seems to automatically scale, so this solution should work)
e.g., you can add
-webkit-mask-image: url(http://f.cl.ly/items/1e181Q0e3j0L3L3z2j3Z/rect.svg)
to your .rc class and it should work in Chrome.
edit: this only seems to work if you remove your inline height and width declarations on your video... You can put them in your CSS, though.
http://jsfiddle.net/QWfhF/2/
Try this. It should work.
-webkit-mask: url(mypath/mask.png);
where the mask.png should be a rounded corner shape.
Did this quick with a circle.
[url removed]
Update October 2019
Border-radius for video now works on firefox, chrome and safari on mac, android and iOS.
Chrome Mobile Bug - if some Chrome android browsers cause you problems with rounding just add the following property to the video css. It's just a 1px transparent image which solves the chrome border-radius rendering bug for android phones
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
Test it here - https://jsfiddle.net/hzd4vec2/
<!DOCTYPE html>
<html>
<head>
<title>Border-radius test</title>
<style type="text/css">
body{
background: #000000;
margin: 0px;
}
#capsule{
height: 600px;
background: #000;
border-radius: 1000px;
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
}
</style>
</head>
<body>
<video id="capsule" src="http://clips.vorwaerts-gmbh.de/VfE_html5.mp4"
autoplay muted loop></video>
</body>
</html>
Tested on Chrome, Firefox, and Safari:
CSS:
.rounded {
border-radius: 20px;
overflow: hidden;
-webkit-transform: translateZ(0);
}
HTML:
<div class="rounded">
<video>.....</video>
</div>
remove the width property
http://jsfiddle.net/vDPW2/10/
Try read this: http://www.gerbenvanerkelens.com/1778/let%E2%80%99s-talk-about-the-html5-video-tag/
And for CSS would be:
video{
width:320px;
-moz-border-radius:40px;
-webkit-border-radius:40px;
border-radius:40px;
overflow:hidden;
}
This can be done with canvas and JavaScript at least (Introduction how to manipulate video frame data with canvas). You basically draw a new canvas, apply the video frame data there, then clip the rounded corners off. I created this quickly, so didn't check whether the anti-aliasing could have been improved, but at least it does the rounding. Performance wise, you can imagine this isn't really as good as applying CSS or something, but it should work on all canvas supported browsers at least.
var video = document.getElementById("video");
var c1 = document.getElementById("roundy");
var ctx = c1.getContext("2d");
video.addEventListener("play", function() {
timerCallback();
}, false);
var timerCallback = function() {
if (video.paused || video.ended) {
return;
}
computeFrame();
setTimeout(function () {
timerCallback();
}, 0);
};
var computeFrame = function() {
var w = 480;
var h = 320;
var r = 20;
ctx.clearRect(0,0,w,h);
ctx.globalCompositeOperation = 'destination-atop';
ctx.fillStyle = "#09f";
roundRect(ctx, 0,0,w,h,r,true,false);
ctx.drawImage(video, 0, 0, w, h);
return;
}
// http://js-bits.blogspot.com/2010/07/canvas-rounded-corner-rectangles.html
function roundRect(ctx, x, y, width, height, radius, fill, stroke) {
if (typeof stroke == "undefined" ) {
stroke = true;
}
if (typeof radius === "undefined") {
radius = 5;
}
ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
ctx.lineTo(x + width, y + height - radius);
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
ctx.lineTo(x + radius, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
ctx.lineTo(x, y + radius);
ctx.quadraticCurveTo(x, y, x + radius, y);
ctx.closePath();
ctx.clip();
}
Example: http://jsfiddle.net/niklasvh/aFcUh/ (play the top video to view the effects on the bottom canvas one).
class="img-rounded" from bootstrap works fine for me using video.js
<link href="//vjs.zencdn.net/4.3/video-js.css" rel="stylesheet">
<script src="//vjs.zencdn.net/4.3/video.js"></script>
<video id="example_video_1" class="video-js vjs-default-skin img-rounded"
controls preload="auto" width="640" height="264">
<source src="http://example.com/test_video.mp4" type='video/mp4'/>
</video>
Following solution works on my site with video tag and youtube embedded
.video{
border-radius: 10px;
overflow: hidden;
z-index: 1;
height: 480px; /*it can deleted, if height is not restricted*/
width: 640px;
}
<div class="video">
<iframe width="640" height="480" src="https://www.youtube.com/embed/..." frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe>
</div>
<div class="video">
<video controls>
<source src="..." type="video/mp4">
</video>
</div>
UPD
I had issue with youtube embedded iframe, container .video had height bigger 3px than its child iframe. And it made bottom corners a little bit incorrect.
Just add font-size: 0 to .video class, fixed the problem
.video{
border-radius: 10px;
overflow: hidden;
z-index: 1;
font-zie: 0
height: 480px; /*it can deleted, if height is not restricted*/
width: 640px;
}
I got this working for modern browsers with a parent (div) and the video inside.
The parent has the border-radius: 8px and overflow: hidden. The video just needs display: grid to make the bottom edged rounded too.
I accomplished this using only CSS and a sprite image. This works in all browsers and does not require any JavaScript.
By surrounding the video with a div that is set to position: relative; you can place four divs in each of the four corners on top of the video using z-index and absolute positioning. Then place a sprite background image into each of the four corners that rounds the edge with the same color as the background color. Essentially covering the video with an image of a corner.
Here is a working example: http://jsfiddle.net/476tC/
The code for it also located below:
<style>
video {
width: 100%;
height: auto;
}
.corner-frame {
width: 100%;
position: relative;
}
.corner-top-left, .corner-top-right, .corner-bot-left, .corner-bot-right {
width: 10px;
height: 10px;
position: absolute;
background: url(http://i45.tinypic.com/5l520j.png) no-repeat;
z-index: 1;
}
.corner-top-left { top: 0; left: 0; background-position: 0 0 ; }
.corner-top-right { top: 0; right: 0; background-position: -10px 0 ; }
.corner-bot-left { bottom: 4px; left: 0; background-position: 0 -10px ; }
.corner-bot-right { bottom: 4px; right: 0; background-position: -10px -10px ; }
</style>
<div class="corner-frame">
<video controls>
<source src="http://ia700204.us.archive.org/18/items/blue_shoes/blue_shoes.mp4" type="video/mp4">
<source src="http://ia700204.us.archive.org/18/items/blue_shoes/blue_shoes-portable.ogv" type="video/ogg">
</video>
<div class="corner-top-left"></div>
<div class="corner-top-right"></div>
<div class="corner-bot-left"></div>
<div class="corner-bot-right"></div>
</div>
The sprite I created is only 20px x 20px and only rounds about 10px off the corner. If you would like to download the photoshop file and change the corner color or increase the size you can get the PSD file here: http://www.mediafire.com/?bt9j0vhsmzfm9ta
As has been said border-radius does work in Firefox and Chrome depending on video type. I found it necessary to style using video, video::first-child for mp4. There is probably an inner layer(border) to mp4s. I did the first-child bit when I noticed ogg and webm were working whereas mp4 was not.
remove width="320" height="240"from inside of video tag and add to your css file .rc{width:320; height:240; outline:none; border-radius:15px }
I hope this solution is work for you :)
2022 answer:
Set the video height to max-content and simply use the border-radius:
video {
height: max-content;
border-radius: 16px;
}
A better alternative is to use object-fit (plus object-position) if you don't want to mess with the height:
video {
object-fit: cover; /* so the video covers all the available space */
object-position: center; /* not required */
border-radius: 16px;
}
One attribute does the job and can be added as a class directly on the video tag. The class would look like:
.video-mask
{
border-radius: 3em;
}
If you add these properties:
max-width: 100%;
display: block;
margin: auto;
padding: 1em;
You will have a centered responsive rounded video that resizes to keep its aspect ratio and stays in the middle. None of these are strictly necessary though.

HTML5 video background on iPad/iphone

I used this solution to use an html5 video as the background of my site.
However, it doesn't seem to work on iPad/iphone, all I am getting is a black screen, and the video is not resizing.
Also, the video does not resize correctly when the aspect ratio of the window is not the same as the aspect ratio of the video. You will see that the background image begins to become visible.
Thanks!
In http://www.develooping.com/canvas-video-player/ you can see a responsive mp4 background working in iPad/iPhones. Download the code from http://www.develooping.com/wp-content/uploads/2016/04/html-canvas-video-player.zip. It uses an adapted version of HTML canvas video player script by Stanko;
<div class="video-responsive">
<video class="video" muted="muted" loop="loop" autoplay="autoplay">
<source src="mY_movie.mp4" type="video/mp4">
Your browser does not support HTML5 video.
</video>
<canvas class="canvas"></canvas>
<div id="over_video">Look at me</div>
</div>
The script is used as follows
<script src="canvas-video-player.js"></script>
<script>
var isIOS = /iPad|iPhone|iPod/.test(navigator.platform);
if (isIOS) {
var canvasVideo = new CanvasVideoPlayer({
videoSelector: '.video',
canvasSelector: '.canvas',
timelineSelector: false,
autoplay: true,
makeLoop: true,
pauseOnClick: false,
audio: false
});
}else {
// Use HTML5 video
document.querySelectorAll('.canvas')[0].style.display = 'none';
}
</script>
The CSS is
body {
background: #000;
padding:0;
margin:0;
}
.video-responsive {
padding-bottom: 56.25%;
position: relative;
width: 100%;
}
.canvas,
.video {
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
background: #000;
z-index: 5;
}
#over_video{
position: absolute;
width: 100%;
height: 100%;
text-align: center;
top: 0;
z-index: 10;
font-size: 12vw;
color: #FFF;
font-family: Verdana, Arial, Helvetica, sans-serif;
margin-top: 20%;
text-shadow: 4px 4px 4px #5C433B;
}
Hope it can help.
Just mark as record.
Nowadays, the ability of background video get supported (iOS 10 +) due to the new policies of WebKit.
To be specific, check out the official document below.
https://webkit.org/blog/6784/new-video-policies-for-ios/
Since iOS10 there is a solution, see here: https://webkit.org/blog/6784/new-video-policies-for-ios/
On iPhone, <video playsinline> elements will now be allowed to play inline, and will not automatically enter fullscreen mode when playback begins.
<video> elements without playsinline attributes will continue to require fullscreen mode for playback on iPhone.
When exiting fullscreen with a pinch gesture, <video> elements without playsinline will continue to play inline.
Unfortunately, the iPad doesn't support automatic video play, so you'd need a play/stop/pause button. Here's an example of something that does work on iPad: http://html5-fullscreen-video.ceseros.de/html_5_fullscreen/movie/1
SquareSpace uses an interesting approach to "simulating" video on their website by using a clever loop of .pngs and overlays. See http://www.squarespace.com/
If you sift through the HTML you will find the hand sequence here: http://cf.squarespace.com/details/musician-hand-sequence-hires.png
It works on phones.. Just something to think about.
The only way to autoplay videos on mobile devices is to ditch the html video tag.
I see three options, assuming you don't need audio:
Use a gif instead of the video. Depending of the animation, the file size will skyrocket though
Use a really long jpg or png that contains every frame of the video and then shift through them with javascript
Decode the video with javascript. For example use this h.264 decoder and play videos with good compression. Only downside I see is that it requires quite some CPU for the decoding.
I went for the last solution and it works fine.
I have stumbled upon something that might help you with this task..
http://vagnervjs.github.io/frame-player/
Its a JS player that receives a JSON list of images representing frames of the video.
This will also provide flexibility with regards to styling options of the video itself and responsiveness..
You could load a different set of images (lower in quality) to suuport IPADs vs. desktop support for instance.
Most easiest way I think, just use gif for background. For example you can convert it online like in http://ezgif.com/video-to-gif

rounded corners on html5 video

Is there a way I can cut off the corners of my html5 video element using the CSS3 border-radius attribute?
Check out this example. it's not working.
Create a div container with rounded corners and overflow:hidden. Then place the video in it.
<style>
.video-mask{
width: 350px;
border-radius: 10px;
overflow: hidden;
}
</style>
<div class="video-mask">
<video></video>
</div>
We have a video playing with rounded corners and a drop shadow and it's as simple as:
border-radius: 22px;
overflow: hidden;
-webkit-transform: translateZ(0);
box-shadow: 0 19px 51px 0 rgba(0,0,0,0.16), 0 14px 19px 0 rgba(0,0,0,0.07);
The key is the -webkit-transform: translateZ(0). This line of code tells the browser to render on the GPU instead of with the
Tested and working as of Safari 11, Chrome 65, Firefox 59, Edge Win 10 & IE 11
It works in Firefox as long as you set the appropriate 180px height for the 320px width video (16:9 aspect ratio) - otherwise the curved borders aren't visible because they're outside the frame of the video.
There are some outstanding bugs in WebKit to do with it clipping content in concert with border-radius, like this one or this one specifically about the video element.
Unfortunately, Chrome and Safari do not support border-radius on <video> elements.
If all of your videos are the same size, you could use a CSS mask with an SVG file. If your videos are dynamically sized, that makes things more difficult...
(edit: the SVG mask seems to automatically scale, so this solution should work)
e.g., you can add
-webkit-mask-image: url(http://f.cl.ly/items/1e181Q0e3j0L3L3z2j3Z/rect.svg)
to your .rc class and it should work in Chrome.
edit: this only seems to work if you remove your inline height and width declarations on your video... You can put them in your CSS, though.
http://jsfiddle.net/QWfhF/2/
Try this. It should work.
-webkit-mask: url(mypath/mask.png);
where the mask.png should be a rounded corner shape.
Did this quick with a circle.
[url removed]
Update October 2019
Border-radius for video now works on firefox, chrome and safari on mac, android and iOS.
Chrome Mobile Bug - if some Chrome android browsers cause you problems with rounding just add the following property to the video css. It's just a 1px transparent image which solves the chrome border-radius rendering bug for android phones
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
Test it here - https://jsfiddle.net/hzd4vec2/
<!DOCTYPE html>
<html>
<head>
<title>Border-radius test</title>
<style type="text/css">
body{
background: #000000;
margin: 0px;
}
#capsule{
height: 600px;
background: #000;
border-radius: 1000px;
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
}
</style>
</head>
<body>
<video id="capsule" src="http://clips.vorwaerts-gmbh.de/VfE_html5.mp4"
autoplay muted loop></video>
</body>
</html>
Tested on Chrome, Firefox, and Safari:
CSS:
.rounded {
border-radius: 20px;
overflow: hidden;
-webkit-transform: translateZ(0);
}
HTML:
<div class="rounded">
<video>.....</video>
</div>
remove the width property
http://jsfiddle.net/vDPW2/10/
Try read this: http://www.gerbenvanerkelens.com/1778/let%E2%80%99s-talk-about-the-html5-video-tag/
And for CSS would be:
video{
width:320px;
-moz-border-radius:40px;
-webkit-border-radius:40px;
border-radius:40px;
overflow:hidden;
}
This can be done with canvas and JavaScript at least (Introduction how to manipulate video frame data with canvas). You basically draw a new canvas, apply the video frame data there, then clip the rounded corners off. I created this quickly, so didn't check whether the anti-aliasing could have been improved, but at least it does the rounding. Performance wise, you can imagine this isn't really as good as applying CSS or something, but it should work on all canvas supported browsers at least.
var video = document.getElementById("video");
var c1 = document.getElementById("roundy");
var ctx = c1.getContext("2d");
video.addEventListener("play", function() {
timerCallback();
}, false);
var timerCallback = function() {
if (video.paused || video.ended) {
return;
}
computeFrame();
setTimeout(function () {
timerCallback();
}, 0);
};
var computeFrame = function() {
var w = 480;
var h = 320;
var r = 20;
ctx.clearRect(0,0,w,h);
ctx.globalCompositeOperation = 'destination-atop';
ctx.fillStyle = "#09f";
roundRect(ctx, 0,0,w,h,r,true,false);
ctx.drawImage(video, 0, 0, w, h);
return;
}
// http://js-bits.blogspot.com/2010/07/canvas-rounded-corner-rectangles.html
function roundRect(ctx, x, y, width, height, radius, fill, stroke) {
if (typeof stroke == "undefined" ) {
stroke = true;
}
if (typeof radius === "undefined") {
radius = 5;
}
ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
ctx.lineTo(x + width, y + height - radius);
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
ctx.lineTo(x + radius, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
ctx.lineTo(x, y + radius);
ctx.quadraticCurveTo(x, y, x + radius, y);
ctx.closePath();
ctx.clip();
}
Example: http://jsfiddle.net/niklasvh/aFcUh/ (play the top video to view the effects on the bottom canvas one).
class="img-rounded" from bootstrap works fine for me using video.js
<link href="//vjs.zencdn.net/4.3/video-js.css" rel="stylesheet">
<script src="//vjs.zencdn.net/4.3/video.js"></script>
<video id="example_video_1" class="video-js vjs-default-skin img-rounded"
controls preload="auto" width="640" height="264">
<source src="http://example.com/test_video.mp4" type='video/mp4'/>
</video>
Following solution works on my site with video tag and youtube embedded
.video{
border-radius: 10px;
overflow: hidden;
z-index: 1;
height: 480px; /*it can deleted, if height is not restricted*/
width: 640px;
}
<div class="video">
<iframe width="640" height="480" src="https://www.youtube.com/embed/..." frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe>
</div>
<div class="video">
<video controls>
<source src="..." type="video/mp4">
</video>
</div>
UPD
I had issue with youtube embedded iframe, container .video had height bigger 3px than its child iframe. And it made bottom corners a little bit incorrect.
Just add font-size: 0 to .video class, fixed the problem
.video{
border-radius: 10px;
overflow: hidden;
z-index: 1;
font-zie: 0
height: 480px; /*it can deleted, if height is not restricted*/
width: 640px;
}
I got this working for modern browsers with a parent (div) and the video inside.
The parent has the border-radius: 8px and overflow: hidden. The video just needs display: grid to make the bottom edged rounded too.
I accomplished this using only CSS and a sprite image. This works in all browsers and does not require any JavaScript.
By surrounding the video with a div that is set to position: relative; you can place four divs in each of the four corners on top of the video using z-index and absolute positioning. Then place a sprite background image into each of the four corners that rounds the edge with the same color as the background color. Essentially covering the video with an image of a corner.
Here is a working example: http://jsfiddle.net/476tC/
The code for it also located below:
<style>
video {
width: 100%;
height: auto;
}
.corner-frame {
width: 100%;
position: relative;
}
.corner-top-left, .corner-top-right, .corner-bot-left, .corner-bot-right {
width: 10px;
height: 10px;
position: absolute;
background: url(http://i45.tinypic.com/5l520j.png) no-repeat;
z-index: 1;
}
.corner-top-left { top: 0; left: 0; background-position: 0 0 ; }
.corner-top-right { top: 0; right: 0; background-position: -10px 0 ; }
.corner-bot-left { bottom: 4px; left: 0; background-position: 0 -10px ; }
.corner-bot-right { bottom: 4px; right: 0; background-position: -10px -10px ; }
</style>
<div class="corner-frame">
<video controls>
<source src="http://ia700204.us.archive.org/18/items/blue_shoes/blue_shoes.mp4" type="video/mp4">
<source src="http://ia700204.us.archive.org/18/items/blue_shoes/blue_shoes-portable.ogv" type="video/ogg">
</video>
<div class="corner-top-left"></div>
<div class="corner-top-right"></div>
<div class="corner-bot-left"></div>
<div class="corner-bot-right"></div>
</div>
The sprite I created is only 20px x 20px and only rounds about 10px off the corner. If you would like to download the photoshop file and change the corner color or increase the size you can get the PSD file here: http://www.mediafire.com/?bt9j0vhsmzfm9ta
As has been said border-radius does work in Firefox and Chrome depending on video type. I found it necessary to style using video, video::first-child for mp4. There is probably an inner layer(border) to mp4s. I did the first-child bit when I noticed ogg and webm were working whereas mp4 was not.
remove width="320" height="240"from inside of video tag and add to your css file .rc{width:320; height:240; outline:none; border-radius:15px }
I hope this solution is work for you :)
2022 answer:
Set the video height to max-content and simply use the border-radius:
video {
height: max-content;
border-radius: 16px;
}
A better alternative is to use object-fit (plus object-position) if you don't want to mess with the height:
video {
object-fit: cover; /* so the video covers all the available space */
object-position: center; /* not required */
border-radius: 16px;
}
One attribute does the job and can be added as a class directly on the video tag. The class would look like:
.video-mask
{
border-radius: 3em;
}
If you add these properties:
max-width: 100%;
display: block;
margin: auto;
padding: 1em;
You will have a centered responsive rounded video that resizes to keep its aspect ratio and stays in the middle. None of these are strictly necessary though.