본문 바로가기

개발/NODE

node를 사용하여 ffmpeg 이용하여 ebur128 기준 인코딩


영상 파일의 오디오를 ebur128 기준에 맞춰서 인코딩


영상을 ebur128 기준으로 맞춰달라는 요청이 있었다. 인코딩 디코딩도 아는게 없는 분야인데 ebur128이라니?

어쨌든 관련된 내용들을 구글 검색을 진행하여 하나하나 찾아봤다.


1. ffmpeg와 관련 라이브러리들 설치

* ffmpeg 설치는 ebur128 라이브러리를 설치 후 진행하도록 한다.


centos - http://yujuwon.tistory.com/entry/CentOS-ffmpeg-%EC%84%A4%EC%B9%98

ubuntu - http://yujuwon.tistory.com/entry/%EC%9A%B0%EB%B6%84%ED%88%AC%EC%97%90%EC%84%9C-ffmpeg-%EC%84%A4%EC%B9%98-%EB%B0%A9%EB%B2%95


테스트는 centos에서 진행하였는데 막상 상용에 적용하려니 centos 서버가 아닌 

ubuntu서버라는 아주 그지같은 상황이 발생하였지만 감사하게도 정리가 잘 되어 있는 블로그가 있었다.

다만 ubuntu의 경우에는 cmake 설치 시 버그인지 뭔지 서버 로그인 시 콘솔창에 알수 없는 문장 3줄이 출력이 되어서... 

ffmpeg를 설치하고 cmake를 삭제하였다;; 원인을 아시는분은 답변좀..



2. ebur128 라이브러리 설치

ebur128 - https://github.com/jiixyj/libebur128

ebur128 라이브러리를 설치 후 1번을 기준으로 ffmpeg 관련 라이브러리 설치를 진행하였다면 

"ffmpeg_build/lib" 디렉토리가 생성이 되었을 것이다. 해당 디렉토리에 ebur128의 라이브러리 파일(libebur128.a)을 복사하고  

"ffmpeg_build/include" 디렉토리에 ebur128의 헤더 파일(ebur128.h)을 복사 한다.



3. ffmpeg 설치

1번의 절차를 따라 설치를 진행하는데 PATH="$PATH:$HOME/bin" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure --prefix="$HOME/ffmpeg_build" --extra-cflags="-I$HOME/ffmpeg_build/include" --extra-ldflags="-L$HOME/ffmpeg_build/lib" --bindir="$HOME/bin" --extra-libs="-ldl" --enable-gpl --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-x11grab --enable-libebur128

ebur128 라이브러리를 추가하여 설치를 진행한다.


뭔가 정신없이 기술을 하였는데 짧게 정리를 해보면 

a. ffmpeg 관련 라이브러리들을 설치 

b. ebur128 라이브러리를 설치

c. 최종적으로 ebur128 라이브러리를 추가하여 ffmpeg를 설치



4. ebur128의 기준이란?

솔직히 모르겠습니다. 음향쪽 용어들이 나오고 생소한 용어를 찾아보면 용어의 뜻을 이해 못해서 그걸 또 찾아야 되는 아주 그지같은 

뫼비우스의 상황이 발생이 되므로 제가 찾은 가이드 라인은 이렇습니다.


타겟레벨(-23 LUFS +/- 1) 

트루피크(-1dB TP이하)


네, 잘 모르겠습니다. 그래도 참고라도 하기 위해 링크를 남깁니다.

참고1 - http://www.sonycreativesoftware.com/webhelp/soundforgepromac/2.0/ENU/Content/Loudness_Meters.htm

참고2(pdf 파일) - https://www.google.co.kr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0ahUKEwjmkfDhwZ_OAhVIkZQKHcdBBooQFggiMAA&url=http%3A%2F%2Fwww.mediacube.co.kr%2Fboard%2Fdown.php%3Ftb%3Dhome_notice%26fn%3D%25B5%25F0%25C1%25F6%25C5%25D0_%25B9%25E6%25BC%25DB%25C0%25BB_%25C0%25A7%25C7%25D1_%25BF%25C0%25B5%25F0%25BF%25C0_%25C7%25C1%25B7%25CE%25BC%25BC%25BD%25CC%25B0%25FA_%25B0%25F8%25C1%25DF%25C6%25C4_TV_%25B6%25F3%25BF%25EC%25B5%25E5%25B4%25CF%25BD%25BA_%25BA%25D0%25BC%25AE_201201.pdf&usg=AFQjCNHef4gvTzx4xq44WNqvUwDWYZGFnw&sig2=Dp4Z-DKRe1kXcriCHuC7Iw&cad=rjt



5. ebur128 적용해보기

참고 - http://k.ylo.ph/2016/04/04/loudnorm.html

위 링크를 참고하여 ffmpeg 명령들이 제대로 동작이 된다면 ffmpeg 관련 설치가 제대로 된 것입니다.

링크에 적용된 가이드를 기준으로 node를 이용해서 프로그램을 구현할 생각입니다.


Dual-pass mode

5.1. 영상 loudnorm 정보 추출

$ffmpeg -i in.wav -af loudnorm=I=-16:TP=-1.5:LRA=11:print_format=json -f null -

{
        "input_i" : "-27.61",
        "input_tp" : "-4.47",
        "input_lra" : "18.06",
        "input_thresh" : "-39.20",
        "output_i" : "-16.58",
        "output_tp" : "-1.50",
        "output_lra" : "14.78",
        "output_thresh" : "-27.71",
        "normalization_type" : "dynamic",
        "target_offset" : "0.58"
}

5.2. 추출한 loudnorm 정보를 기준으로 loudnorm 인코딩

$ffmpeg -i in.wav -af loudnorm=I=-16:TP=-1.5:LRA=11:measured_I=-27.61:measured_LRA=18.06:measured_TP=-4.47:measured_thresh=-39.20:offset=0.58:linear=true:print_format=summary -ar 48k out.wav

Input Integrated:    -27.5 LUFS
Input True Peak:      -4.5 dBTP
Input LRA:            18.1 LU
Input Threshold:     -39.2 LUFS

Output Integrated:   -16.0 LUFS
Output True Peak:     -1.5 dBTP
Output LRA:           14.6 LU
Output Threshold:    -27.2 LUFS

Normalization Type:   Dynamic
Target Offset:        +0.0 LU



6. node ffmpeg 설치

설치 & 가이드 좀 읽어보시면 금방 이해 되실겁니다.

node ffmpeg - https://github.com/fluent-ffmpeg/node-fluent-ffmpeg


ffmpeg loudnorm 문서 참고



7. node 파일 작성

5.1. ~ 5.2. 콘솔창에서 명령어를 통해 확인할 수 있는 내용들을 node로 작성한것입니다. 

다만 ebur128 가이드에 맞춰 타겟레벨은 '-23'을 트루피크는 '-1'로 맞췄습니다.

var Ffmpeg = require('fluent-ffmpeg'); var fs = require('fs'); var parsedLoudnorm = { input_i : "", input_tp : "", input_lra : "", input_thresh : "", target_offset : "" } var audioFrequency = ""; var cmd; Ffmpeg('input 영상 경로') .audioFilters('loudnorm=I=-23:TP=-1:print_format=json') .format('null') .on('error', function(err) { console.log('An error occurred: ' + err.message); }) .on('end', function(stdout, stderr) { var tempHz = stderr.split('Audio'); tempHz = tempHz[1].split('\n'); tempHz = tempHz[0].split(','); tempHz = tempHz[1].split('Hz'); audioFrequency = tempHz[0].replace(/ /g, '');

// 데이터 추출 var tempLoudnorm = stderr.split('{'); tempLoudnorm = tempLoudnorm[1].replace(/\n/g, '').replace(/\t/g, '').replace(/"/g, '').replace(/ /g, '').replace(/}/g, ''); tempLoudnorm = tempLoudnorm.split(','); parsedLoudnorm.input_i = tempLoudnorm[0].split(':')[1]; parsedLoudnorm.input_tp = tempLoudnorm[1].split(':')[1]; parsedLoudnorm.input_lra = tempLoudnorm[2].split(':')[1]; parsedLoudnorm.input_thresh = tempLoudnorm[3].split(':')[1]; parsedLoudnorm.target_offset = tempLoudnorm[9].split(':')[1]; cmd = 'loudnorm=I=-23:TP=-1:' + 'measured_I=' + parsedLoudnorm.input_i + ':' + 'measured_TP=' + parsedLoudnorm.input_tp + ':' + 'measured_thresh=' + parsedLoudnorm.input_thresh + ':' + 'offset=' + parsedLoudnorm.target_offset + ':' + 'linear=true:print_format=summary'; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Ffmpeg('input 영상 경로') .videoCodec('copy') .audioFrequency(audioFrequency) .audioFilters(cmd) .on('error', function(err) { console.log('An error occurred: ' + err.message); }) .on('end', function() { console.log('Processing finished !'); }) .save('output 영상 경로'); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }) .save('/kbw/video/out.null');


이래저래 변환은 된것 같긴한데... 이게 기준에 맞게 변환이 된건지 확인할 방법은 없었습니다. 

영상 소리의 변화가 있었다 정도로만 파악하고 작업을 종료하였습니다.



잘못된 정보는 바로 지적해 주세요.


'개발 > NODE' 카테고리의 다른 글

이클립스에서 Node 설정  (0) 2016.10.13
node update  (0) 2016.10.12
Node Express를 이용한 Cookie Set  (1) 2016.03.16
NODE를 이용하여 LOL API 호출  (0) 2016.03.11
NPM으로 설치한 SCP2 모듈의 문제 발생  (0) 2016.03.02