admin管理员组

文章数量:1406937

I have a video (let's call it posite video) posed by multiple other videos concatenated using some pattern. For example, see the screenshot of the videos below, posed by two and four other videos, respectively:

However, I need to display it differently: One main, larger, video and N-1 video thumbnails, where N is the total number of videos. Here are this other display corresponding to the videos above:

To display the main I'm using a bination of HTML and CSS to position the video I want in the larger div. It runs smoothly, no matter the number of videos in the posite videos.

To display the thumbnails, I'm using <canvas> to draw the parts I want:

video.addEventListener('play', function() {
  (function loop() {
    drawThumbnails();
    setTimeout(loop, 1000 / 30); // drawing at 30fps
  })();
}, false);

function drawThumbnails() {
  for (var i = thumbs.length - 1; i >= 0; i--) {
    drawThumbnail(thumbs[i]);
  };
}

function drawThumbnail(thumb) {
  var thumbNumber = Number(thumb.id.match(/\d+/g));
  var canvasContext = thumb.getContext('2d');
  var thumbCoordinates = getVideoCoordinates(thumbNumber);
  var srcX = thumbCoordinates.column * videoWidth;
  var srcY = thumbCoordinates.row * videoHeight;

  canvasContext.drawImage(
      video, srcX, srcY, videoWidth, videoHeight, // Source
      0, 0, thumb.width, thumb.height); // Destination
}

It was working well for 3 (sometimes 4) videos. However, as the number of videos in the posite video increases, the videos in the thumbnails start to freeze and run not in a smooth way. This is probably happening because there's too much image processing being done at the same time.

I think the proper way to do it is, somehow, using <video> and methods specific for videos, not for images. I've also tried to use the same src in the multiple <video> tags (one for each thumbnail) and add eventListeners to play/pause the videos in the thumbnails once the main video is played/paused. That's not very efficient, particularly because videos can get out of sync sometimes, when seeking/buffering.

Is there a way of using only one video in multiple <video> tags and use only one of them (in my case, the one that contains the main video) to control all the others? In case there's no way of doing that, is there an alternative approach for my problem?

Thanks a lot,

P.S. Having multiple, separated, videos is not an option in my situation. It would take a very long time to process the input video and divide it in multiple videos.

I have a video (let's call it posite video) posed by multiple other videos concatenated using some pattern. For example, see the screenshot of the videos below, posed by two and four other videos, respectively:

However, I need to display it differently: One main, larger, video and N-1 video thumbnails, where N is the total number of videos. Here are this other display corresponding to the videos above:

To display the main I'm using a bination of HTML and CSS to position the video I want in the larger div. It runs smoothly, no matter the number of videos in the posite videos.

To display the thumbnails, I'm using <canvas> to draw the parts I want:

video.addEventListener('play', function() {
  (function loop() {
    drawThumbnails();
    setTimeout(loop, 1000 / 30); // drawing at 30fps
  })();
}, false);

function drawThumbnails() {
  for (var i = thumbs.length - 1; i >= 0; i--) {
    drawThumbnail(thumbs[i]);
  };
}

function drawThumbnail(thumb) {
  var thumbNumber = Number(thumb.id.match(/\d+/g));
  var canvasContext = thumb.getContext('2d');
  var thumbCoordinates = getVideoCoordinates(thumbNumber);
  var srcX = thumbCoordinates.column * videoWidth;
  var srcY = thumbCoordinates.row * videoHeight;

  canvasContext.drawImage(
      video, srcX, srcY, videoWidth, videoHeight, // Source
      0, 0, thumb.width, thumb.height); // Destination
}

It was working well for 3 (sometimes 4) videos. However, as the number of videos in the posite video increases, the videos in the thumbnails start to freeze and run not in a smooth way. This is probably happening because there's too much image processing being done at the same time.

I think the proper way to do it is, somehow, using <video> and methods specific for videos, not for images. I've also tried to use the same src in the multiple <video> tags (one for each thumbnail) and add eventListeners to play/pause the videos in the thumbnails once the main video is played/paused. That's not very efficient, particularly because videos can get out of sync sometimes, when seeking/buffering.

Is there a way of using only one video in multiple <video> tags and use only one of them (in my case, the one that contains the main video) to control all the others? In case there's no way of doing that, is there an alternative approach for my problem?

Thanks a lot,

P.S. Having multiple, separated, videos is not an option in my situation. It would take a very long time to process the input video and divide it in multiple videos.

Share Improve this question asked Jan 29, 2016 at 20:23 Amaury MedeirosAmaury Medeiros 2,2394 gold badges27 silver badges43 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 1

You can certainly reference the same video across multiple video elements. Cloning the original and appending them as thumbnail videos might alleviate some of the tedium.

Iterating over the thumbnails and .play()ing them should be fine so long as you set their currentTime with that of the main video prior to playing, to minimize drift. There may be some need to wait for canplay to fire on the main video and/or the thumbnails depending on the exact experience you're looking to deliver.

If each thumbnail is given a parent container you could possibly position the video element serving as your thumbnail such that only the portion of the video you care to see is visible, clipping the rest.

FWIW, CSS masking might be of interest to you as a performance optimization if it helps the positing performance.

You will need to manually coordinate playing/pausing all of the video elements, but that should be easy enough to do with a facade object that handle the play pause of all the "linked" video elements.

I know I'm posting late, and you may have already found an answer. However, if anyone else es across this question, here is my answer:

You can use multiple video elements with the same source. The way to do it is with css.

.wrapper {
    height: /*height of one video*/;
    width: /*width of one video*/;
    overflow: hidden;
}
video {
    position: relative;
    top: /*height offset*/;
    left: /*width offset*/;
}

And HTML

<div class="wrapper">
    <video src="myvideo.mp4"></video>
</div>

So, if I was doing the top right video, and each one was 250px by 250px, I would set my wrapper height and width to 250px and my video top to 0px and my video left to 250px

What's the format of the main video? Is it an on demand mp4/webm file?

If you still want to go with your approach of grabbing frames and paint them but is facing performance issues, consider using web workers for the heavy jobs. Here you can find some examples of video/canvas manipulation with web workers.

本文标签: javascriptDisplay same video in multiple ltvideogt tagsStack Overflow