On my site, I have a static-width embedded chromeless YouTube player (iframe) that plays a video selected by the user. It's working well, but there's one little annoyance: its height does not respond to the video; cinematic ultra-widescreen videos have horizontal black bars and old-style 4:3 videos have vertical black bars.
Is there a reasonably simple solution that will make the player adjust its height according to the video it's playing? All Google reveals are scripts for fluid-layout sites (which mine is not). Javascript, Coffeescript, and Jquery solutions are all acceptable.
In order to achieve your expected behavior, you need to know the video's aspect ratio. You can do that quite easily using the API YouTube provides. First, to grab the video info in JSON format, you GET a URL of this form:
https://gdata.youtube.com/feeds/api/videos/video_id?v=2&prettyprint=true&alt=json
Where video_id is the ID of the video you're embedding (note that "prettyprint" just makes it human-readable -- remove it in the actual application to save bandwidth). The property that we care about is entry.media$group.yt$aspectRatio.$t. That property is set to "widescreen" when the video is 16:9, and it isn't defined if it's 4:3. Thus, you can easily check for that value and resize your <iframe> accordingly.
Here's an example:
HTML:
<iframe id = "vid" width="500" src="http://www.youtube.com/embed/ni9RS4pgRXA" frameborder="0" allowfullscreen></iframe>
(Width here is 500 -- it can be, of course, anything you want).
JavaScript (uses jQuery, but it isn't necessary):
$.getJSON("https://gdata.youtube.com/feeds/api/videos/ni9RS4pgRXA?v=2&alt=json",
function(data) {
var obj = $("#vid");
var asp = data.entry.media$group.yt$aspectRatio.$t;
console.log("Aspect Ratio is", asp); //Debugging line. "undefined" if video is 4:3.
if(asp == "widescreen") {
obj.height((Math.floor(obj.width() * 9 / 16)));
}
else {
obj.height((Math.floor(obj.width() * 3 / 4)));
}
});
Here (link) you can find a working demo with an example 16:9 video. The Javascript code is pretty straight-forward, but in case anything is vague, please tell me so that I can explain in more detail.
Related
I want to embed a video in a simple, largely JavaScript-free web page. But I have two versions, one at 1920x1080 and one at 960x540. Ideally, the latter should be used in a smaller embedded window to save the user download, but the former if they go full screen on a PC.
I was expecting to see something on the <Source> element, but could not find it. I would think that it is a very common requirement.
Is there a fairly easy way to do this? Or do we just make the user always use the big file?
(One option is to put the small one inline, and then put a direct link to the full video after it, if the user clicks the latter they get the full resolution.)
The video contains a lot of text, so the larger one does look better full screen. It is twice as large though. (Handbrake compressed at 30 quality.)
If there was some widely used JavaScript control that would be good. But I do not want to have a dependency on a large framework such as React or Angular. This is essentially a static web page.
There are no media queries available for the video tag. You're stuck with JS or HLS streaming to create responsive video on the web.
Here's a simple JS example that will do what you are looking for.
<div id="video"> </div>
<script>
//get screen width and pixel ratio
var width = screen.width;
var smallVideo= <smallvideo>;
var bigVideo = <bigVideo>;
if (width<500){
console.log("this is a very small screen, no video will be requested");
}
else if (width< 1400){
console.log("let’s call this mobile sized");
var videoTag = "\<video preload=\"auto\" width=\"100%\" autoplay muted controls src=\"" +smallVideo +"\"/\>";
document.getElementById('video').innerHTML = videoTag;
}
else{
var videoTag = "\<video preload=\"auto\" width=\"100%\" autoplay muted controls src=\"" +bigVideo +"\"/\>";
document.getElementById('video').innerHTML = videoTag;
}
</script>
What is the "Source" you expect?
I'm not sure but maybe you can handle it by javascript.
In html, just show that former video, then when user interact with this, you can redircet to latter video.
I'm making a video player in AS3 and was wondering how to find out how much of the video is currently cached/buffered. I'm not sure what the correct terminology is, so I haven't been able to find it in the documentation.
NetStream.time gives me the current location of the video, so based on that I can display a progressbar.
Underneath the progressbar, I want to display how much of the video has been loaded already. How do I find this value?
You can use NetSteam.bytesLoaded and NetSteam.bytesTotal to get the total rough percentage loaded:
var bufferPercent:Number = myNetStream.bytesLoaded / myNetStream.bytesTotal;
// Use percentage to scale buffer bar.
myBufferBar.scaleX = bufferPercent;
I've been Googling around a bit for an answer and haven't found a definitive one either way: is it possible to play a video using an HTML5 canvas, and also allow the user to draw on this video? The use case, for some context, is to play a video on infinite loop so the user can draw multiple boxes over specific areas to indicate regions of interest.
As a bonus (:P), if I can figure out how to do this on its own, any hints as to how this could be done within Drupal? I'm already looking at the Canvas Field module, but if you have any hints on this point too (though the first one is the priority), that'd be awesome!
You can draw html5 video elements onto a canvas. The drawImage method accepts a video element in the first parameter just like an image element. This will take the current "frame" of the video element and render it onto the canvas. To get fluid playback of the video you will need to draw the video to the canvas repeatedly.
You can then draw on the canvas normally, making sure you redraw everything after each update of the video frame.
Here is a demo of video on canvas
here is a in-depth look into video and the canvas
I recently received this request from a client to provide this feature, and it must be CMS-friendly. The technique involves three big ideas
a drawing function
repeatedly calling upon the same drawing function
using requestAnimationFrame to paint the next frame
Assuming you have a video element already, you'd take the following steps
Hide the video element
Create a canvas element whose height/width match the video element, store this somewhere
Get the context of the canvas element with `canvas.getContext('2d') and also store that somewhere
Create a drawing function
In that drawing function, you would use canvas.drawImage(src, x, y) where src is the edited version of the current frame of the video;
In that drawing function, use recursion to call itself again
I can give you two examples of this being done (and usable for content management systems)
The first is here: https://jsfiddle.net/yywL381w/19/
A company called SDL makes a tool called Media Manager that hosts videos. What you see is a jQuery plugin that takes its parameters from a data-* , makes a request from the Media Manager Rest API, creates a video, and adds effects based entirely on data* attributes. That plugin could easily be tweaked to work with videos called from other sources. You can look at the repo for it for more details on usage.
Another example is here: http://codepen.io/paceaux/pen/egLOeR
That is not a jQuery plugin; it's an ES6 class instead. You can create an image/video and apply a cropping effect with this:
let imageModule = new ImageCanvasModule(module);
imageModule.createCanvas();
imageModule.drawOnCanvas();
imageModule.hideOriginal();
You'll observe, in the ImageCanvasModule class, this method:
drawFrame () {
if (this.isVideo && this.media.paused) return false;
let x = 0;
let width = this.media.offsetWidth;
let y = 0;
this.imageFrames[this.module.dataset.imageFrame](this.backContext);
this.backContext.drawImage(this.media, x, y, width, this.canvas.height);
this.context.drawImage(this.backCanvas, 0, 0);
if (this.isVideo) {
window.requestAnimationFrame(()=>{
this.drawFrame();
});
}
}
The class has created a second canvas, to use for drawing. That canvas isn't visible, it's just their to save the browser some heartache.
The "manipulation" that is content manageable is this.imageFrames[this.module.dataset.imageFrame](this.backContext);
The "frame" is an attribute stored on the image/video (Which could be output by a template in the CMS). This gets the name of the imageFrame, and runs it as a matching function. It also sends in the context (so I can toggle between drawing on the back canvas or main canvas if needed)
then this.backContext.drawImage(this.media, x, y, width, this.canvas.height); draws the image on the back context.
Finally, this appears on the main canvas with this.context.drawImage(this.backCanvas, 0, 0); where I take the backcanvas, and draw it on to the main canvas. So the canvas that's visible has the least amount of manipulations possible.
And at the end, because this is a video, we want to draw a new frame. So we have the function call itself:
if (this.isVideo) {
window.requestAnimationFrame(()=>{
this.drawFrame();
});
This whole setup allows us to use the CMS to output data-* attributes containing the type of frame the user wants to be drawn around the image. the JavaScript then produces a canvasified version of that image or video. Sample markup might look like:
<video muted loop autoplay data-image-frame="wedgeTop">
Does anyone know if html5 video allows objects like buttons, menu, etc connected to the timeline?
Youtube flash player do this: in specific moment, show an object (banner, links, comments) over the video for defined seconds.
thanks
Yes and no,
It's possible to create very interactive video-based presentations using html5 video objects however it requires a lot more than just the video object itself. You can nest video into a canvas object then mess with the actual video image frames, you can overlay any visual html element on top of the video object itself then animate these, you can control the video playback with buttons, click events etc. You can even have the video object control the rest of the page with time-based listeners.
Popcorn.js is really really good and easy to learn, allowing you to do all of what you mentioned.
http://popcornjs.org
http://popcornjs.org/demos
It's not part of the HTML5 video standard, but it's easy to implement manually by wiring up some scripting to the progress event. By looking at the currentTime property of the video object you can decide when to show/hide additional elements.
eg showing an element on top of a video between 1 and 2 seconds into a video:
<video id="v">...</div>
<div id="overlay" style="position: relative; top: -80px;">HELLO</div>
<script type="text/javascript">
var overlay= document.getElementById('overlay');
var video= document.getElementById('v');
video.addEventListener('progress', function() {
var show= video.currentTime>=1 && video.currentTime<2;
overlay.style.visibility= show? 'visible' : 'hidden';
}, false);
</script>
X2TV (www.x2.tv) has a drag and drop studio where you can overlay icons and additional content within the HTML5 layer.
In case you woul like to use a more generic framework https://github.com/nise/vi-two could be interesting for you.
I am trying to embed a flash movie (.flv) into a webpage with a transparent background.
Requirements:
- Flv runs in transparent mode - I must be able to view html contents below.
- Movie does not auto play
- Movie is contained in a div and positionend absolutely using CSS
- No video controls or overlays, you shouldn't know it's an flv
- On load Movie is hidden
- Using jQuery, I click an image link to show and play the video, clicking it again stops and hides the video - vice versa
I have tried using Longtail Video Player with swfobject.js and javascript controls but no joy. Video is not transparent and controls with a click to play still feature.
Am I overcomplicating what appears to be quite a simple task.
I happy to explore any implementation.
Adobe flash embed parameters have been set correctly and wmode = transparent.
Any help would be greatly appreciated.
Cheers
Paul
This will get you a transparent overlay in flash. Its a pretty good set of code.
http://code.google.com/p/swfobject/
SWFObject Examples
The example given above is what you need for the bare bones use of SWFObject, but what if you want to use some of the other parameters the Flash plug-in has to offer? SWFObject makes it very easy to add any extra parameter you may need. The examples below are a number of different methods you may wish to use to embed your Flash content.
A simple example adding a few extra parameters
<script type="text/javascript">
var so = new SWFObject("movie.swf", "mymovie", "200", "100%", "7", "#336699");
so.addParam("quality", "low");
so.addParam("wmode", "transparent");
so.addParam("salign", "t");
so.write("flashcontent");
</script>
<div id="flashcontent"><!--put a place holder image in here.--></div>
http://blog.deconcept.com/swfobject/
EDIT:
THANKS TO Unreality: There has been an update in the code library you can now access it here: http://www.code.google.com/p/swfobject