Enjoy Programming

WebAssembly 본문

JavaScript/Vanilla Js

WebAssembly

LEETAEEON 2021. 6. 25. 12:30

현재 만든 비디오 플레이어는 녹화하고 다운로드해서 webm파일을 얻을 수 있다.

하지만 부족한게 많다. 내 맥북에서는 파일이 webm 이라 구동시 브라우저로 열리고

플레이어 이용시 호환이 안된다.

음 니코의 경우 어떤 플레이어를 쓰는지 모르지만 플레이어 구동시

duration도 안나오고 range조절도 안된다.  이번엔 이것을 수정하는 코드를 짜볼건데

 

FFmpeg를 가지고 mp4로 변환하고 썸네일도 추출할 것이다.

FFmpeg는 디지털 영상스트림과 음성스트림을 다양한 형태로 저장하고 변환하는 컴퓨터 프로그램이다.

https://www.ffmpeg.org/

 

FFmpeg

Converting video and audio has never been so easy. $ ffmpeg -i input.mp4 output.avi     News June 19th, 2021, IRC We have a new IRC home at Libera Chat now! Feel free to join us at #ffmpeg and #ffmpeg-devel. More info at contact#IRCChannels April 8th, 20

www.ffmpeg.org

FFmpeg로 여러가지를 할 수 있다. 영상에서 음성만 추출도 가능하고 비디오를 압축하거나 포맷을 변환하거나  스크린샷을 찍거나~

등등 여러가지를 할 수 있다. 아마 유튜브도 업로드시 ffmpeg를 이용해서 비디오를 여러가지 포맷과 화질로 인코드 하고 있을 것 같다.

 ffmpeg는 컴퓨터에 설치해서 사용가능하다.

그리고 사이트에서 실행하려면 백엔드에서 실행해야만 한다. 서버를 이용해야하는데 아마도 비용이 만만치 않을것이다.

 

이것을 해결해 줄 웹어셈블리가 있는데 웹어셈블리란??

 

https://developer.mozilla.org/ko/docs/WebAssembly

 

웹어셈블리 | MDN

WebAssembly는 최신 웹 브라우저에서 실행할 수 있는 새로운 유형의 코드입니다. 네이티브에 가까운 성능으로 동작하며 컴팩트한 바이너리 포맷을 제공하는 저수준 어셈블리 언어로, C/C++, Rust 등

developer.mozilla.org

이것만 보면 뭐에 쓰는건고~ 싶다.

https://developer.mozilla.org/ko/docs/WebAssembly/Concepts

 

웹어셈블리의 컨셉 - 웹어셈블리 | MDN

본 글에서는 웹어셈블리의 작동원리 뒤에 숨어있는 컨셉을 설명함과 동시에 웹어셈블리의 목표, 웹어셈블리가 해결할 수 있는 문제, 그리고 웹브라우저 렌더링 엔진 안에서 웹어셈블리가 작

developer.mozilla.org

웹 어셈블리는 개방형 표준이다. 기본적으로 웹사이트가 매우 빠른 코드를 실행할 수 있게 해준다.

프론트엔드에서는 HTML, CSS, JAVASCRIPT만 사용할 수 있다.

그런데 웹 어셈블리는 자바스크립트를 쓰지 않고 다른 언어를 사용할 수 있다.

 

이제 매우빠른 웹어셈블리와 ffmpeg를 함께 결합해서 사용해보자.

ffmpeg.wasm을 사용한다. ffmpeg.wasm은 비디오를 변환하기위해 사용자의 컴퓨터를 사용한다.

고로 사용자의 브라우저에서 비디오를 변환하려고 하는 것이다. 나의 서버가 아닌~ 

기존 백엔드에서 multer를 사용해 내 컴퓨터에 파일 url을 저장하는 폴더를 만들고 그파일을 생성했던거랑 비슷하다

다만 브라우저에서 프로그램이 돌아가고 유저의 컴퓨터 메모리에 가상으로 저장되고 있다는것

 

웹어셈블리를 이용해 c로 만들어진 ffmpeg를 웹에서 실행시킬 수 있고~ ffmpeg.wasm을 이용해 사용자의 컴퓨터로 브라우저에서 변환~ 끝

앞선 코드에서는 사용자가 다운로드 버튼을 누르면 영상을 불러서 변환하게 되는 프로세스

중요한것!!! 앞서 만든 레코더에서 브라우저에서 사용가능한 blob된 url을 이용한다! 기억하자.

 

npm install @ffmpeg/ffmpeg @ffmpeg/core 로 설치하고

앞선 레코더 파일에  import {createFFmpeg, fetchFile} from "@ffmpeg/ffmpeg" 임포트 해주자

 

그리고 ffmpeg instance를 만들어줘야 한다.

인스턴스를 만들때 log:true의 역할은 콘솔에서 로그기록을 보기 위해서 이다. 그리고 로드한다.

역시 async await을 사용하자 . 사용자가 자바스크립트를 사용하는 것이 아닌 웹사이트에서 다른 소프트웨어를 사용하게 하는 것이므로

기다려줘야 한다.

 

 

이제 ffmpeg파일을 만들어 주면 되는데

ffmpeg.FS()를 사용하는데 세가지 method가 있다. 이중 writeFile을 이용해 본다. writeFile은 ffmpeg의 가상의 공간에서 파일을 생성해준다. 그리고 파일 이름을 지정해주고 ~ 그다음 파라미터로 binaryData function을 줘야 한다. 이말은 ffmpeg의 가상의 공간에 파일을 생성하기 위해서는 binary 로 정보를 전송해야 한다. 자 binary data는 어디 있을까...

기억하자! blob된 url이 data라는 것을 ~ 그럼 그 데이터는 url로 만들어주었기 때문에 url에 접근하면 데이터에 접근이 된다.

이때 fetchFIle함수를 사용한다.

 

이렇게 ffmpeg파일이 생성된다.

 그러나 아직 뭔가 하고있지는 않다. ffmpeg명령어를 입력해줘야 한다.

위의 -i는 input을 의미한다. 가상의 공간에 존재하는 RecrodFile.webm을 input으로 ffmpeg.run이 받는다.

그리고 output파라미터로 output.mp4를 지정해주면 RecordeFile.webm 인풋 파일이 ouput.mp4로 아웃풋 된다.

그리고 기존의 실행 방식대로 그냥 녹화후 다운로드를 클릭하고 콘솔창을 보면~~~ 와우

인코딩 되고있다~ 인코딩이 완료되면 파일이 생성되는데 아직 이 파일을 다운로드 하진 않는다.

현재는 webm을 다운로드 하게 해놨으니까.. 현재 output.mp4는 브라우저의 메모리에 있다.

이제 파일 시스템을 통해 해당 파일을 불러와보자

파일을 불러와 콘솔창에 출력하는데 이파일은 unsigned int의 형태이다. 부호없는 정수의 형태~그리고 array로 반환된다.

짜잔.. 엄청난 array파일이다... 어떻게 읽을 수 가 없다..ㅋㅋㅋ 이제 blob을 이용할텐데.

blob이란?  binary large Object!

자바스크립트에서 블랍은 이미지, 사운ㄷ, 비디오와 가은 멀티미디어 데이터를 다룰 때 사용할 수 있다.

대게 데이터의 크기 및 mime타입을 알아내거나, 데이터 송수신을 위한 작은 blob객체로 나누는 등의 작업에 사용한다.

 

mdn에 따르면 blob객체는 파일류의 불변하는 미가공 데이터를 나타낸다. 텍스트와 이진 데이터의 형태로 읽을 수 있으며

readableStream으로 변환한 후 그 메서드를 사용해 데이터를 처리 할 수 도 있다.

blob은 자바스크립트 네이티브형태가 아닌 데이터도 표현 가능하다. file인터페이스는 사용자 시스템의 파일을 지원하기 위해

blob인터페이스를 확장한 것이므로 모든 블롭기능을 상속한다.

 

blob이 아닌 겍체와 데이터에서 blob을 생성하려면 blob()생성자를 사용한다.

다른 블롭의 일부에서 새로운 블롭을 생성할때는 slice()메서드를 사용할 수 있다.

https://developer.mozilla.org/ko/docs/Web/API/Blob

 

Blob - Web API | MDN

Blob 객체는 파일류의 불변하는 미가공 데이터를 나타냅니다.

developer.mozilla.org

mdn을 살펴보자~!~!

 

이제 이용해보자  현재 uint8array로 부터 blob을 만들 수는 없지만 arraybuffer로는 만들 수 있다.

.. arraybuffer는 뭐냐! 역시 mdn으로 가보자

 

arraybuffer 객체는 일반적인 고정 길이 원시 이진 데이터 버퍼를 나타낸다.

arraybuffer는 바이트로 구성된 배열로, 다른 언어에서는 종종 바이트배열이라고 부른다. 

arraybuffer에 담긴 정보를 직접 수정하는 것은 불가능하지만, 대신 형식화 배열이나 dataview를 통해 버퍼를 특정 형식으로 나타내고

이를 통해 버퍼의 내용을 읽거나 쓸 수 있다.

 

arraybuffer() 생성자는 주어진 길이를 가진 새로운 arraybuffer를 성생헌다. 또한 base64문자열이나 로컬 파일 처럼

기존 데이터에서 배열 버퍼를 생성할 수도 있다.

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer

 

ArrayBuffer - JavaScript | MDN

ArrayBuffer 객체는 일반적인 고정 길이 원시 이진 데이터 버퍼를 나타냅니다.

developer.mozilla.org

복잡해진다.. 일단 기억하자 uint8array에서 buffer를 이용하면

raw binary data를 사용할 수 있다.

 

각설하고 blob을 사용해서 만들어보자.

blob은 배열안에 배열을 넣어주고 자바스크립트에거 파일의  타입을 알려준다.

 

이미 녹화할때 blob을 만들었었다. 그땐 ondataavaialbe을 이용해 녹화가 끝나면 데이터를 받는데 그때 자동으로 blob파일이 생성되었고 이것을 url로 만들어 준것이다. blob파일을 만들어 주었으니

똑같이 url로 만들어준다!! 그래야 클릭하면 해당 url에 접근해 파일에 접근할 수 있도록!

한번 실행해보자~!

콘솔창에 output이 뜨고~ 다운로드 창에 mpeg-4가 보인다~

그리고 html에도 blob링크가 생성되었다~~~

다운로드도 잘받아지고~ 실행도 잘된다~!~!~! 이제 썸네일을 만들고 스크린샷도 추가하자~

'JavaScript > Vanilla Js' 카테고리의 다른 글

[ES6] Symbol  (0) 2021.07.02
webAssemply 2  (0) 2021.06.25
download for recorded video  (0) 2021.06.23
MediaRecorder  (0) 2021.06.23
MediaDevices.getUserMedia()  (0) 2021.06.23