WebRTC 오산 문제를 넘어. 로컬 파일을 자유롭게 조작하고 싶습니다.

소개



이전 기사 "WebRTC를 시도할 때 오산이 계속 비치는 문제를 해결" 은 예기치 않은 반향을 받았습니다. 이번은 그 속편으로서 로컬 파일로부터 미디어 스트림을 만들어 여러가지 조작해 보았습니다.

그 후에 알게 된 것



이전 기사를 쓴 후에 코멘트를 받거나, 스스로 시험하거나 해, 알았던 적이 있습니다.
  • Canvas나 Web Audio를 사용하지 않고도 video 태그나 audio 태그로부터 직접 captureStream() 할 수 있다
  • Firefox 47에서는 접두사가있는 mozCaptureStream ()을 사용할 수 있습니다.
  • Chrome에서도 가까운 장래에 captureStream ()을 사용할 수있게된다

  • 동영상계의 파일로부터, 음성만 꺼내 변환할 수 있다
  • 오디오 태그로 동영상 파일의 오디오 만 재생 가능
  • Web Audio에서 오디오 만 변환 가능
  • ※ 일부러 영상 파일과 음성 파일을 별도로 준비할 필요는 없다


  • 마지막 기사와 같이 어리석은 처리는 더 이상 필요하지 않습니다. 기쁩니다, 분한 것입니다.

    굳이 Canvas가 필요한 케이스를 만들어



    잃어버린 아낌없이 굳이 Canvas를 사용하여 미디어 스트림으로 변환하는 샘플을 만들어 보았습니다. 2개의 영상 파일을 준비해, 자유롭게 바꿀 수 있도록 한 것이 이쪽입니다.

    2개의 영상 전환





    전환 모드 동영상은 이쪽으로부터(m4v 형식, 14MB)
    ※이번에도 이쪽의 NHK 크리에이티브 라이브러리 의 소재를 사용해 주셨습니다.

    샘플 페이지, 소스 코드



    Chrome 51, Firefox 47에서 실행할 수 있습니다.
  • GitHub Pages에서 시도 switch_to_stream.html
  • GitHub에서 보기 switch_to_stream.html

  • 위의 애니메이션처럼 조작하기 전에 먼저 영상 파일×2, 음성 파일×1을 지정하고, [Start]하고 나서 즐겨 주십시오.


    메커니즘



    구조라고 해도, 파일로부터 미디어 스트림에 변환하는 방법은 마지막 기사 에 기재한 내용과 같습니다. 그래서 2개의 영상을 Canvas로 합성하는 부분에 대해 설명합니다.

    스와이프의 경우


  • 슬라이더가 0 일 때는 비디오 1의 내용을, 100 일 때는 비디오 2의 내용을 Canvas에 전사합니다.
  • 그렇다면 그 비율에 따라 video의 일부를 잘라내어 drawImage()로 전사합니다.

    30이면 비디오 1은 70 %, 비디오 2는 30 % 비율입니다.




  • swipe
          let video1Width = Math.round((100- faderValue)/100.0 * localVideo.videoWidth);
          let video2Width = Math.round(faderValue/100.0 * localVideo2.videoWidth);
          let canvasWidth1 = Math.round((100- faderValue)/100.0 * duplicateCanvas.width);
          let canvasWidth2 = Math.round(faderValue/100.0 * duplicateCanvas.width);
    
          if (canvasWidth1 > 0) {
            ctxDuplicate.drawImage(localVideo, 0, 0, video1Width, localVideo.videoHeight,
              0, 0, canvasWidth1 , duplicateCanvas.height
            );
          }
    
          if (canvasWidth2 > 0) {
            ctxDuplicate.drawImage(localVideo2, (localVideo2.videoWidth - video2Width), 0, video2Width, localVideo2.videoHeight,
              (duplicateCanvas.width - canvasWidth2), 0, canvasWidth2 , duplicateCanvas.height
            );
          }
    

    스트라이프의 경우



    전체를 10개로 분할해, 그 1열마다 스와이프와 같은 처리를 실시하고 있습니다.


    디졸브의 경우



    한쪽을 비쳐 가면서 다른 한쪽으로 전환하는 디졸브의 처리는에 대해서는 globalAlpha라는 지정을 사용하여 실현하고 있습니다.


    dissolve
          let video1Alpha = (100 - faderValue)/100.0;
          let video2Alpha = (faderValue)/100.0;
    
          ctxDuplicate.globalAlpha = video1Alpha;
          ctxDuplicate.drawImage(localVideo, 0, 0, localVideo.videoWidth, localVideo.videoHeight,
            0, 0, duplicateCanvas.width , duplicateCanvas.height
          );
    
          ctxDuplicate.globalAlpha = video2Alpha;
          ctxDuplicate.drawImage(localVideo2, 0, 0, localVideo2.videoWidth, localVideo2.videoHeight,
            0, 0, duplicateCanvas.width , duplicateCanvas.height
          );
    

    변환된 미디어 스트림은, RTCPeerConnection 로 통신 상대에게 송신할 수가 있습니다. (※ new MediaStream() 로 오브젝트를 만들고 있기 때문에, 현재는 Firefox에서는 에러가 되어 버립니다)

    결론



    로컬 파일을 굳이 Canvas를 사용하여 변환하는 예를 소개했습니다. VJ 기분으로 영상을 바꾸면서 전달한다는 것이 브라우저만으로도 할 수 있게 되네요. (※기존의 동영상/음성 파일을 사용하는 경우에는, 그 이용 조건은 존중해 이용해 주십시오. 잘 부탁드립니다)

    HTM ㅇ x 페rts. jp 라고 하는 사이트에서 「WebRTC 입문 2016」 라고 하는 연재도 쓰고 있으므로, WebRTC에 흥미를 가진 분은 그쪽도 보실 수 있으면 기쁩니다.

    좋은 웹페이지 즐겨찾기