<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>quasar-kim.log</title>
        <link>https://velog.io/</link>
        <description>학생</description>
        <lastBuildDate>Mon, 20 Jun 2022 17:26:44 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. quasar-kim.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/quasar-kim" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[ffmpeg.wasm이 큰 파일을 다룰 수 있게 하려고 한 개고생 정리(1)]]></title>
            <link>https://velog.io/@quasar-kim/ffmpeg.wasm%EC%9D%B4%EB%9E%91-File-System-Access-API%EB%A5%BC-%EA%B0%99%EC%9D%B4-%EC%93%B0%EA%B8%B0-%EC%9C%84%ED%95%9C-%EA%B0%9C%EA%B3%A0%EC%83%9D-%EC%A0%95%EB%A6%AC1</link>
            <guid>https://velog.io/@quasar-kim/ffmpeg.wasm%EC%9D%B4%EB%9E%91-File-System-Access-API%EB%A5%BC-%EA%B0%99%EC%9D%B4-%EC%93%B0%EA%B8%B0-%EC%9C%84%ED%95%9C-%EA%B0%9C%EA%B3%A0%EC%83%9D-%EC%A0%95%EB%A6%AC1</guid>
            <pubDate>Mon, 20 Jun 2022 17:26:44 GMT</pubDate>
            <description><![CDATA[<h2 id="주의">주의</h2>
<p>본인은 전문가가 아닙니다. 글에서 전문성을 기대하지 말아주세요. 내가 한 일을 정리도 하고 누군가에게 도움이 될 수도? 있지 않을까 하는 생각에서 글을 적어봅니다.</p>
<hr>
<p>주말에 쉬고 있다가 브라우저에서 WebAssembly를 이용해서 ffmpeg를 쓸 수 있으면 재미있지 않을까?란 생각이 갑자기 들어서 이 고생은 시작됐다.</p>
<p>찾아보니 이미 어떤 분이 <a href="https://github.com/ffmpegwasm/ffmpeg.wasm">ffmpeg.wasm</a> 레포지토리를 통해서 웹어셈블리 버전 ffmpeg를 배포하고 있었다. </p>
<p><img src="https://velog.velcdn.com/images/quasar-kim/post/e127663e-ada8-4d03-945d-2e9c3e8eaae8/image.png" alt="ffmpeg.wasm 프로젝트 페이지"></p>
<p>그런데 한계가 있었는데... 이 프로젝트는 emscripten이 제공하는 인메모리 파일 시스템을 사용해서 큰 파일을 넣으면 브라우저가 죽어버린다는 거였다.</p>
<p>그걸 확인하고 든 생각.</p>
<blockquote>
<p>내가 직접 고쳐보지 뭐</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/quasar-kim/post/20b57c24-8de6-490b-aaff-d2bfc21f558e/image.jpg" alt="그거 아니야"></p>
<h1 id="목표">목표</h1>
<p>내가 목표로 삼은 건 두가지였다.</p>
<ol>
<li>emscripten의 인메모리 파일 시스템인 <code>MEMFS</code> 대신 큰 파일을 다룰 수 있는 <code>WORKERFS</code>를 적용시켜서 큰 파일을 입력받을 수 있도록 하자.</li>
<li>File System Access API를 이용해 출력을 메모리 대신 바로 디스크에 쓰자.</li>
</ol>
<p>이 글에서는 1의 일부분만 다룹니다.</p>
<h1 id="emscripten의-file-system-api">Emscripten의 File System API</h1>
<p><a href="https://emscripten.org/">Emscripten</a>은 웹 어셈블리 프로젝트 개발을 위해서 개발된 툴체인이라고 한다. 가장 큰 특징은 기존 C, C++ 툴체인의 Drop-in replacement라는 거다. 그러니깐 기존 프로젝트에서 <code>gcc</code>쓰듯 <code>emcc</code> 컴파일러를 쓰면 된다는건데... 솔직히 이쪽은 잘 모르니깐 일단 넘어가자.</p>
<p> 기존의 ffmpeg같은 프로젝트가 브라우저에서 정상적으로 돌아가려면 파일 시스템이 브라우저상에서 구현되어야 한다. 문서를 읽어보면 <code>MEMFS</code>, <code>IDBFS</code>, <code>WORKERFS</code>등 다양한 파일 시스템 구현이 존재한다는 걸 확인할 수 있다. 이중 아무런 설정도 안하면 기본으로 포함되는 <code>MEMFS</code>는 인메모리 파일 시스템이다. 그러니깐 마치 메모리를 디스크 쓰듯이 쓰게 되는 것이다. 가장 간단하지만, 메모리에다가 바로 파일을 써버리기 때문에 큰 파일을 쓰려고 하면 메모리가 나가버린다. </p>
<p><code>WORKERFS</code>는 파일을 모두 메모리에 저장하지 않는 대신 처음에 받는 <code>File</code> 오브젝트를 이용해서 필요한 데이터만 가져오는거로 추정된다. (확인해보지는 않았지만 아마 그럴듯...) 그래서 이걸 이용하면 큰 파일을 지원할 수 있을거라고 생각하고, 이걸 적용해보기로 했다. </p>
<p>문제는 이 파일 시스템은 웹 워커 환경에서만 동작하며, 읽기만 지원하고(그러니깐 쓰기가 안된다!), 별도로 설정을 해주어야 했다는 것이다. 웹 워커는 쓰기 쉬우니깐 별 문제가 안되지만 읽기만 지원한다는 게 문제였다. 일단 이 부분은 나중에 생각해보기로 해보고 읽기라도 되게 해보기 위해서 <code>WORKERFS</code>를 적용시킬 방법을 찾아보았다.</p>
<p>ffmpeg.wasm 레포지토리에서 관련 이슈를 찾아보니 어떤 사람이 이미 설정을 다 해 놓은 <a href="https://github.com/animebook/ffmpeg.wasm-core">레포지토리</a>를 찾을 수 있었다. 이걸 clone하고 도커에서 컴파일 돌리면 되겠지?라고 생각했는데...</p>
<h1 id="컴파일해보자">컴파일해보자!</h1>
<p>일단 컴파일을 위해서 레포지토리를 클론했다. 참고로 본인은 개발용으로 윈도우 10 컴퓨터에서 WSL2를 올려서 쓰고 있다.</p>
<pre><code># 윈도우 10에서 실행
git clone https://github.com/animebook/ffmpeg.wasm-core
cd ffmpeg.wasm-core</code></pre><p>그다음 다음 명령어를 실행해서 도커에서 컴파일을 돌렸다.</p>
<pre><code># WSL2로 환경 바꿈
./build-with-docker.sh</code></pre><p>그러면 도커가 알아서 적절한 이미지를 다운받고 격리된 환경에서 완벽하게 컴파일을 해줘야...하는데... 오류가 나네????</p>
<pre><code>./configure: 1: eval: aac_adtstoasc_bsf
=yes: not found</code></pre><p>구글링을 해봐도 나오지도 않는 오류다... 도대체 왜???????</p>
<p><img src="https://velog.velcdn.com/images/quasar-kim/post/149848d9-219d-4415-b2b7-e203076d678a/image.png" alt="?????????"></p>
<h2 id="디버깅-지옥">디버깅 지옥</h2>
<p>본인은 bash 언어를 다룰줄 모른다. 그런데 저 오류를 낸 <code>./configure</code>이란 스크립트는 확인해보니 무려 7000라인짜리 bash 스크립트였다. 현실을 부정하며 명령어를 몇번을 다시 돌려봐도 결과는 똑같았다. </p>
<p>그다음으로 든 생각은 디버깅을 해보자는 거였다. 그런데 bash에도 디버거가 있나? 찾아보니 정말 다행이도 <a href="http://bashdb.sourceforge.net/">bashdb</a>라는 디버깅 프로그램과 대응되는 vscode 확장도 있었다. 이유는 모르겠는데 최신 버전의 우분투에는 이 프로그램이 빠져있어서 공식 사이트에서 파일을 받아 패키지를 직접 설치하고 vscode로 도커 컨테이너에 연결해 디버깅을 시작했다.</p>
<p>맨땅에 해딩하듯이 bash 언어를 stackoverflow의 도움을 받아서 조금씩 배워나가면서 스크립트를 돌려나갔다. 한줄 돌리고 모르는거 찾아보고를 계속하면서 약 2시간쯤이 지났을때쯤 스크립트에서 이상한 점을 하나 발견할 수 있었다.</p>
<p><img src="https://velog.velcdn.com/images/quasar-kim/post/22b16e14-d82f-4045-9bb8-60ddf40aa4a1/image.png" alt="">
이 부분을 디버거로 돌려보니 볼 수 없었던 오류 메시지를 볼 수 있었다. 정확한 메시지는 기억나지 않지만 분명 위에서는 <code>eval $var=$value</code>였는데 디버깅 콘솔에는 <code>eval $val=\r$value</code>라고 출력되어 있었던 것 같다.</p>
<p><code>\r</code>이 뭐였지...? 바로 폭풍검색을 해본 결과... 마침내 문제의 원인을 찾을 수 있었다!! (아래는 검색의 흔적이다) <img src="https://velog.velcdn.com/images/quasar-kim/post/5dedc040-41b8-4837-a12d-00c47703f333/image.png" alt="새벽 3시에 폭풍검색"></p>
<h2 id="사람-잘못">사람 잘못</h2>
<p><img src="https://velog.velcdn.com/images/quasar-kim/post/f7f85360-6aba-497a-986c-2c45f118f39c/image.png" alt="문제의 원인">
<code>\r</code>은 Carriage Return이란 문자로 윈도우 환경에서 개행문자로 <code>\n</code>(line feed)와 함께 사용된다. 그건 원래 알고 있었는데... 도대체 왜 이게 스크립트 중간에 끼어있는 거지??? 기억을 되돌려본 결과 진짜 원인을 발견할 수 있었다. 바로 나는 프로젝트를 <strong>윈도우 10 환경에서 클론</strong>했던 것이었다!</p>
<p>git에는 <code>autocrlf</code>라는 기능이 있어서 서로 다른 운영 체제 간 개행 문자의 차이를 신경써도 되지 않게 해 준다. 윈도우에서 git을 설치하면 기본적으로 <code>autocrlf</code> 기능이 활성화되어 있으며, 이 기능이 켜져있으면 git은 프로젝트를 <code>clone</code>등으로 불러올 때 <code>lf</code>를 몽땅 <code>crlf</code>로 바꾸고 반대로 커밋할때는 <code>crlf</code>를 <code>lf</code>로 바꿔서 커밋시킨다. </p>
<p>나는 이 <code>autocrlf</code> 기능이 켜져있는 윈도우 10 환경에서 clone을 해서 git이 정말 고맙게도 프로젝트의 개행문자를 <code>crlf</code>로 죄다 바꿔버렸는데 이 과정에서 알 수 없는 오류로 인해 저 위치에 <code>\r</code>이 끼어들어간 것이었다.</p>
<h2 id="고치기">고치기</h2>
<p>원인을 알아내자 정말 어이가 날아갔지만 일단 고치는게 최우선이니 고칠 방법을 찾아봤다. 정말 고맙게도 누군가 <code>dos2unix</code>라는 좋은 프로그램을 만들어둬서 이걸 이용해서 프로젝트의 모든 파일의 개행 문자를 바꿨다.</p>
<pre><code>dos2unix **/*</code></pre><p>그리고 컴파일해보니 다행이도 정상적으로 컴파일이 되었다.</p>
<h1 id="교훈">교훈</h1>
<p>다음부터는 WSL에서 클론해야겠다.</p>
]]></description>
        </item>
    </channel>
</rss>