안녕하세요:) 개발자 우디입니다! 아래 내용 관련하여 작업 중이신 분들께 도움이되길 바라며 글을 공유하니 참고 부탁드립니다😊
(이번에 벨로그로 이사오면서 예전 글을 옮겨적었습니다. 이 점 양해 부탁드립니다!)
메인 프로세스
가 여러 개의 렌더러 프로세스를 관리하는 구조메인 프로세스
에서 하는 것이며, 메인 프로세스는 node 기반으로 동작하므로 파일 시스템 접근 등 Node.js API(https://nodejs.org/dist/latest-v16.x/docs/api/)를 모두 사용할 수 있음main.js 에 영상 클립 내보내서 하나의 파일로 병합하는 함수 makeClipsAndMerge
클립으로 내보내기
let makeClip = ffmpeg(videoPath);
...생략...
makeClip
.setStartTime(startTime)
.setDuration(endTime - startTime)
.withSize(resolution)
.outputOptions(videoQuality)
.output(savedClipPath)
.on('progress', function (progress) {
// 내보내기 과정의 progress를 파악하기 위함
...생략...
})
.on('end', function (err) {
// 내보낸 클립들 평합하는 코드 삽입
...생략...
})
.on('error', function (err) {
// 에러 발생 시 실행될 코드 삽입
...생략...
})
.run();
{
root: 'C:\\',
dir: 'C:\\path\\dir',
base: 'file.txt',
ext: '.txt',
name: 'file'
}
내보낸 클립 병합하기
let mergedVideo = ffmpeg();
...생략...
videoNames.forEach(function (videoName) {
mergedVideo.addInput(videoName);
});
mergedVideo
.mergeToFile(selectedFilePath, tmpPath)
.outputOptions(videoQuality)
.on('progress', function (progress) {
// 병합 과정의 progress를 파악하기 위함
...생략...
})
.on('error', function (err) {
// 내보낸 클립들 평합하는 코드 삽입
...생략...
})
.on('end', function () {
// 에러 발생 시 실행될 코드 삽입
...생략...
});
속도 높이기 위한 하드웨어 가속
클립 생성 및 병합 과정에서 아래와 같이 inputOptions 설정하면 됨
.inputOptions([
'-hwaccel cuda',
'-c:v h264_cuvid',
])
사용자 하드웨어 환경 파악
import { getGPUTier } from 'detect-gpu';
this.isCudaSupported = '';
...생략...
detectUserGpu = () => {
(async () => {
const userGpu = await getGPUTier();
// Example output:
// {
// device: undefined
// fps: 694
// gpu: "nvidia geforce rtx 3070"
// isMobile: false
// tier: 3
// type: "BENCHMARK"
// }
let isNvidiaContained = userGpu['gpu'].toUpperCase().includes('NVIDIA');
let isProperTier = userGpu['tier'] >= 2;
//NVIDIA 포함, Tier가 2이상일 경우만 true
if (isNvidiaContained & isProperTier) {
this.isCudaSupported = true;
} else {
this.isCudaSupported = false;
}
})();
};
가속 여부 테스트
화질 옵션 고려하기
사용자가 선택한 옵션에 따라 출력되는 영상의 화질이 달라져야 함
출력되는 결과에 대한 옵션이니까 fluent-ffmpeg 의 outputOptions 을 활용하면 되지 않을까 생각함
영상의 화질을 결정하는 요소?
옵션에 따른 화질 테스트
function makeClipsAndMerge(...) {
...
makeClip
.setStartTime(startTime)
.setDuration(endTime - startTime)
.inputOptions([
"-hwaccel cuda",
"-c:v h264_cuvid"
])
.videoCodec("h264_nvenc")
.withSize(resolution)
.outputOptions(videoQuality)
.output(savedClipPath)
...
}
기타 공유하고 싶은 점
이슈1) memory leak 문제 발생
// 기존 코드
videoNames.forEach(function(videoName){
mergedVideo
.addInput(videoName)
.videoBitrate(videoQuality)
});
// 개선된 코드
videoNames.forEach(function(videoName){
mergedVideo.addInput(videoName)
});
이슈2) 클립 생성은 잘 되는데, 병합 단계에서 에러 발생하는 경우
Error ffmpeg exited with code 1: Cannot find a matching stream for unlabeled input pad 114 on filter Parsed_concat_0
이슈3) 하드웨어 가속 안되는 경우 발생