본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


Node.js

FFMPEG를 활용한 간단한 웹 비디오 에디터(web video editor) - 2

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2021. 9. 1.

ffmpeg를 활용하여 제작하여본 웹 비디오 에디터(영상편집기) 2번째 내용 입니다.

 * 이전 글 참조 : https://lts0606.tistory.com/518

 

남은 기느은 3번, 4번, 5번에 대한 기능 입니다.
 * 1번 : 영상을 업로드  (완료)
 * 2번 : 영상을 시간별로 분할 (완료)
 * 3번 : 원하는 영상의 특정 시간을 잘라내기, 잘라낸 작업 취소
 * 4번 : 잘라낸 구간의 영상을 다른 영상으로 생성

 

#3. 자르기, 자른 작업 취소

구간별 영상에 대한 영역을 만들 때 고려해야되는 점은 영상의 인덱스 입니다.
10초짜리 영상이 존재한다면 사진은 0번부터 9번까지의 인덱스를 부여 할 수 있습니다.

아래 사진을 살펴보도록 합니다.

인덱스, 시간

 

동영상에서 추출한 사진들은 고유의 인덱스 값을 가지고 있습니다.

인덱스는 맨 처음 영역을 만들 때 부여하여 주도록 합니다.

이러한 인덱스는 영상의 실제로 관리되는 고유번호 입니다.

내용이 어려우므로 사용자가 4초와 5초 구간을 잘라냈다고 가정을 한 경우를 살펴 봅니다.

4초와 5초를 잘라냅니다.

 

이렇게 4초와 5초를 잘라내면 아래 사진처럼 나오게 됩니다.

새로운 4초와 5초가 탄생 하였습니다.

 

4초와 5초가 잘라진 뒤에 새로운 4초와 5초가 만들어 졌지만 고유 인덱스는 변화하지가 않았습니다.

그러면 인덱스의 변화를 살펴 보면, 기존에 1씩 증가하던 인덱스가 아니라,

0, 1, 2 까지 증가하다 갑자기 5,6,7,8,9가 나오게 됩니다.

그러면 인덱스 0~2까지는 1개의 구간, 인덱스 5~9까지는 1개의 구간으로 볼 수 있습니다.

 

이러한 2개 구간을 각각의 동영상으로 원본 영상에서 시간을 잘라내어 만들어 줍니다.

표현된 시간값으로 자르는 것이 아니라, 고유 인덱스를 시간으로 잘라내 주면 됩니다.

만들어준 동영상을 1개로 합치게 되면 비로소 사용자가 원하는 4초와 5초가 잘린 동영상이 나오게 됩니다.

결국 3개의 영상이 생기는 것 입니다.

 

기능 구현을 위해서는 브라우저에서 선택된 영역의 값을 배열에 담고 꺼내는 기능을 붙여 줍니다.

그러한 배열의 값을 통해서 화면에서 지우거나, 또는 배열의 값을 삭제 함으로써 지우기를 취소하는 기능을 나타낼 수 있습니다.

음...세부 코드 설명은 아래 깃헙페이지에서 확인하여주세요. 설명이 어렵네요..^-^;

 

영상 구간을 잘라낸 뒤에 영상을 생성하기 위해서 서버로 인덱스 값을 전달 합니다.

ffmpeg에서 제공되는 함수인 setVideoStartTime와 setVideoDuration를 사용하면 시간만큼 원본 영상에서 잘라낼 수 있습니다. 그리고 save 함수를 통해서 새로운 영상을 생성 하도록 합니다.

각각의 구간별로 영상이 생성되면  fluent-ffmpeg 라이브러리를 사용하여 잘라진 영상들을 합치도록 하면 됩니다.

* (서버)영상을 자르고 합치는 코드 샘플

    new ffmpeg( targetMP4File,  (err, video)=>{
        if (!err) {
            let fileNames = []
            element.forEach( arg=>{
                fileNames.push(makeid(20) + '.mp4')
            })
            let index = 0
            function looper(){
                return new Promise( (succ,fail) => {
                    if(index == element.length) return succ()
                    try {
                        video
                        .setVideoStartTime(element[index][0] !=0 ? element[index][0]-1 : 0)  
                        .setVideoDuration(element[index].length != 1 ? element[index].length -1 : 1)   
                        .save(tmpPath + fileNames[index], (error, file)=>{
                            if(!error){
                                console.log('change time!', index)
                            } else {
                                console.log('change time!', error)
                            }
                            index = index + 1
                            succ(looper())  //끝날 때 까지 재귀
                        })                               
                    } catch (error) {
                        fail(error)
                    }             
                })
            }                

            looper().finally( ()=>{
                const concatMP4FileTmpPath = tmpPath   //임시 저장 디렉토리
                const concatMP4FilePath = newPath + makeid(20) + '.mp4'  //합쳐질 파일 위치,이름
                console.log(concatMP4FileTmpPath)
                console.log(concatMP4FilePath)
                let mergedVideo = fluent_ffmpeg()

                fileNames.forEach(element => {  //목록 추가하기
                    mergedVideo = mergedVideo.addInput(tmpPath + element)    
                })

                mergedVideo.mergeToFile(concatMP4FilePath, concatMP4FileTmpPath) //파일 1개로 만들기
                .on('error', function(err) {
                    if(calback) calback(null)
                })
                .on('end', function() {
                    if(calback) calback(concatMP4FilePath)
                })
            })
        }
    })

 

위 내용까지를 구현한 모습 입니다.

아래 동영상으로 확인 할 수 있습니다.

브라우저에서 시간에 대한 영역 선택은 어렵지 않는 기술 입니다.

 

#4. 잘라낸 구간 다른영상으로 생성

선택된 영상을 잘라내서 다른 영상으로 생성하는 것은 3번기능을 구현 하였다면 매우 쉽습니다.

선택된 영상을 바로 서버로 전송하여 새로운 영상을 만들도록 하면 끝이기 때문 입니다.

그러므로 브라우저에는 2가지 타입의 배열이 존재 합니다.

1개는 잘라낸 영역이 담긴 배열, 1개는 새로운 영역을 만들 배열

위 2개의 이벤트를 따로 분리하여 준 다면 간단한 영상편집 기능이 완성되게 됩니다.

 

영상을 미리보기 형식으로 재생하는 기능도 만들어 보았습니다..  : - )

 

간단한 기능 위주로 구현하여 보았습니다.

"미리보기" 에 해당하는 영역에 이미지를 추가하여 "섬네일" 같은 기능도 가능할 것 같습니다.

물론 영상에 이미지를 추가하여 주는 것은 ffmpeg가 쉽게 구현을 해 주겠지요.

 

위 내용에 대한 최종 소스코드는아래 깃허브에서 살펴볼 수 있습니다.

https://github.com/TaeSeungRyu/sample/tree/main/웹비디오에디터

 

GitHub - TaeSeungRyu/sample

Contribute to TaeSeungRyu/sample development by creating an account on GitHub.

github.com

 

이상으로 FFMPEG를 활용한 간단한 웹 영상편집기에 대해서 살펴보았습니다.

* 이전글 : FFMPEG를 활용한 간단한 웹 비디오 에디터(web video editor) - 1

댓글 또는 메일로 언제든 연락주세요👻

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글