首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >可以在javascript中旋转视频块吗?

可以在javascript中旋转视频块吗?
EN

Stack Overflow用户
提问于 2022-01-07 21:07:19
回答 1查看 490关注 0票数 0

我试图旋转视频标签,并将其置于“图片中的图片”模式,

我知道我们可以使用transform: rotateY(180 mode )旋转视频,但是css不会在"pip“模式下应用于视频。

所以我想,如果我们能旋转它的块,然后以"pip“模式调用它

这是密码,任何建议请..。

代码语言:javascript
运行
复制
const cameraRecording = async function(micStatus){
    try{
        const stream = await navigator.mediaDevices.getUserMedia({
            video : true, 
            audio: micStatus ? false : true
        });
        cameraRecElem.srcObject = stream;
        record(stream, true);
    }
    catch(err){
        showError('Error accessing camera or microphone');
    }
};
代码语言:javascript
运行
复制
const record = function(stream, pipStatus, stream2){

    recorder = new MediaRecorder(stream);

    recorder.addEventListener('start', (e) =>{
        chunks = [];
        if(pipStatus) cameraRecElem.requestPictureInPicture() && (cameraRecElem.style.opacity="0");
    });

    recorder.addEventListener('dataavailable', (e) =>{
        chunks.push(e.data);
    });

    recorder.addEventListener('stop', (e) =>{
        stream.getTracks().forEach(track => track.stop());
        if(stream2) stream2.getTracks().forEach(track => track.stop());
        clearInterval(counting);
        setLink(chunks);
        if(pipStatus) document.exitPictureInPicture();
    });

    startCountDown();
    recorder.start();
}
EN

回答 1

Stack Overflow用户

发布于 2022-01-27 06:20:51

为此,我们需要遍历HTML元素,在那里执行镜像,并使用从这个画布中捕获的流。

新的VideoCodecsMediaStream可集成 API在以出色的方式从MediaStream抓取帧的过程中有很大的帮助,但不幸的是,很显然,在画布上不绘制所述帧的情况下,也没有简单的方法来镜像该帧并生成新的MediaStream。

对于不支持HTML的浏览器,我们必须通过一个WebCodecs视频元素,它将播放MediaStream并在画布上绘制该视频元素。

以下是我认为最具表现力的方法:

代码语言:javascript
运行
复制
document.querySelector("button").onclick = (evt) => {
  evt.currentTarget.remove();
  const stream = getCanvasStream();
  const mirrored = mirrorStream(stream);
  document.querySelector("video.default").srcObject = stream;
  document.querySelector("video.mirrored").srcObject = mirrored;
};

function mirrorStream(stream) {
  const canvas = document.createElement("canvas");
  Object.assign(canvas, { width: 0, height: 0 });
  const ctx = canvas.getContext("2d");
  const track = stream.getVideoTracks()[0];
  const drawOnCanvas = (image, width, height) => {
    // MediaStream's video size may change over time
    if (canvas.width !== width || canvas.height !== height) {
      canvas.width = width;
      canvas.height = height;
      ctx.setTransform(-1, 0, 0, 1, width, 0);
    }
    ctx.clearRect(0, 0, width, height);
    ctx.drawImage(image, 0, 0);
  };
  // the MediaStreamTrackProcessor API is available, we use it
  if (window.MediaStreamTrackProcessor) {
    const processor = new MediaStreamTrackProcessor(track);
    const reader = processor.readable.getReader();
    reader.read().then(function readChunk({ done, value }) {
      const { displayWidth, displayHeight } = value;
      drawOnCanvas(value, displayWidth, displayHeight);
      value.close(); // close the VideoFrame when we're done with it
      if (!done) {
        reader.read().then(readChunk);
      }
    });
  } else {
    const vid = document.createElement("video");
    vid.srcObject = stream;
    // in case requestVideoFrameCallback is available, we use it
    // otherwise we fallback on rAF
    const scheduler = vid.requestVideoFrameCallback ?
        (cb) => vid.requestVideoFrameCallback(cb) : requestAnimationFrame;
    const draw = () => {
      const { videoWidth, videoHeight } = vid;
      drawOnCanvas(vid, videoWidth, videoHeight);
      scheduler(draw);
    };
    vid.play().then(draw);
  }
  return canvas.captureStream();
}

// StackSnippet only:
// because StackSnippet don't allow the use of gUM
// we return a MediaStream from a simple <canvas> anim
function getCanvasStream() {
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");
  ctx.font = "30px sans-serif";
  ctx.textAlign = "center";
  ctx.textBaseline = "middle";
  function anim() {
    ctx.fillStyle = "white";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = "black";
    ctx.fillText(new Date().toTimeString().split(" ")[0], canvas.width / 2, canvas.height / 2);
    requestAnimationFrame(anim);
  }
  anim();
  return canvas.captureStream();
}
代码语言:javascript
运行
复制
video { width: calc(50vw - 10px); border: 1px solid; }
代码语言:javascript
运行
复制
<button>begin</button><br>
<video autoplay controls class="default">
</video><video autoplay controls class="mirrored">
</video>

作为一个使用JSFiddlegetUserMedia()

请注意,如果您确实想要垂直镜像视频,那么通过使用createImageBitmap(VideoFrame, { imageOrientation: "flipY" })MediaStreamTrackGenerator,我们可以在没有画布的情况下做到这一点,但是没有办法以这种方式进行水平镜像。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70627193

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档