Today
-
Yesterday
-
Total
-
  • 스트리밍 파일 저장 일대기 (2) - 동영상 파일 생성
    Soliloquy 2018. 7. 14. 15:20

    FFmpeg 로고

     

    비디오 파일과 오디오 파일을 받았으니 이제 2500개의 영상 파일과 2500개의 오디오 파일들을 하나의 파일로 합치는 작업만 남았다. 합치는 작업은 FFmpeg로 합치기로 했다. FFmpeg는 https://www.ffmpeg.org/download.html#build-windows 를 통해 받았다.

     

    합치기

     

    비디오/오디오 각각 하나로 만들기

    우선 2500개의 동영상 파일을 먼저 합치기로 했다. 합치는 방법은 FFmpeg 위키에 나와 있었다. 파일을 하나로 합치기 위해서는 파일 위치가 적힌 텍스트 파일을 만들어야 했다.

     

    file 'D:\videoplayback(1)'
    file 'D:\videoplayback(2)'
    file 'D:\videoplayback(3)'

    ... 

    file 'D:\videoplayback(2500)'

    텍스트 파일 내용

     

    D:\videoplayback(1 ~ 2500) 2500개를 어떻게 적을까 고민하다가 엑셀을 사용하기로 했다. videoplayback(1) 부터 videoplayback(2500) 까지 금방 만들었다. 엑셀은 정말 만능이다.

     

    그리고 ffmpeg -f concat -safe 0 -i list.txt -c copy output.ts 를 통해 비디오 파일을 만들려고 했다. 그런데 텍스트 파일이 유효하지 않다는 뜬금 없는 메세지가 나왔다. 알고보니 ' 대신 "로 파일 위치를 표기한게 원인이었다.

     

    D:\>ffmpeg -f concat -safe 0 -i list.txt -c copy output.ts


    ffmpeg version 3.4.2 Copyright (c) 2000-2018 the FFmpeg developers
      built with gcc 7.3.0 (GCC)
      configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-bzlib

      libavutil      55. 78.100 / 55. 78.100
      libavcodec     57.107.100 / 57.107.100
      libavformat    57. 83.100 / 57. 83.100
      libavdevice    57. 10.100 / 57. 10.100
      libavfilter     6.107.100 /  6.107.100
      libswscale      4.  8.100 /  4.  8.100
      libswresample   2.  9.100 /  2.  9.100
      libpostproc    54.  7.100 / 54.  7.100

     

    [concat @ 00000030de1424a0] Impossible to open '"D:video2videoplayback(1)"
    '
    list.txt: Invalid argument

     

    에러 메세지

     

    처음에 파일을 만드는 데는 생각보다 오래 걸리지는 않았다.

     

    D:\>ffmpeg -f concat -safe 0 -i list.txt -c copy output.ts

    ...

    [mov,mp4,m4a,3gp,3g2,mj2 @ 000000599ab3bec0] Auto-inserting h264_mp4toannexb bit
    stream filter
    Input #0, concat, from 'list.txt':
      Duration: N/A, start: 0.000000, bitrate: 77 kb/s
        Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(progressiv

    ...

    video:232kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing o
    verhead: 14.389732%

    ...

     

    그리고 성공적으로 만들어 졌다.

     

    그리고 동일한 방법으로 오디오 파일도 하나의 .aac 파일로 만들었다.

     

    만들어진 2개의 파일

     

    지나치게 긴 동영상 시간

    그리고 지나치게 짧은 비트레이트

     

    여기서 하나 신기한 일이 있었는데 타임스탬프가 어떻게 되었는지, 비디오 파일의 길이가 1시간 20분이 아닌 23시간 35분이 나왔다. 재생은 되나 궁금해서 재생을 해봤는데 재생도 잘된다. 게다가 플레이어 스크롤 바도 잘 당겨진다. 다만, 23시간을 등분해서 움직여 재생시 스크롤바 움직임이 엄청 느리다. 표기되는 시간과 영상 은 당연히 안맞다

     

    1시간 같은 25시간

    이제보니 윈도우(23)랑 팟플레이어(25)랑 표기 시간도 다르다.

     

    1시간 대로 바꿀 수는 없을 까 하고 열심히 인터넷을 찾아봤는데, 찾기가 힘들었다. 그래서 혹시나 ts 를 mp4 형식으로 바꾸면 될까 해서

     

    ffmpeg -i output.ts -c copy d:\output2.mp4

     

    를 통해 변경해 봤는데 이번에는 정확한 시간을 표시해 주었다.

     

    이번에는 제대로 보여준다.

     

    비디오,오디오 하나로 합치기

    이제 아까 만든 mp4 파일과 .aac 파일을 하나로 합칠 차례다. 아까 처럼 비디오/오디오 파일을 각각 하나의 파일로 만든 방법대로 만드니 신기하게도, 용량은 거의 둘 다 합친 용량이 맟는데, 비디오가 안나왔다. 이 방법이 아닌가 보다.

     

    그래서 인터넷에서 이것 저것 다 해보다가 무슨 명령어인지 지금은 기억이 안나지만, 합친 파일이 만들어지다가 Error parsing ADTS frame header! 라는 에러가 발생하는 일이 있었다. .aac 파일도 뭔가 잘못됬나 싶어서 m4a 로 바꿔보았지만[각주:1], 역시 똑같이 에러가 발생했다. 이것만 해결하면 이제 다 만들었다 라는 생각에 여기에 관해 엄청 많이 뒤져봤는데, 결국 못찾았다. 에러가 발생하는 원인이 생각보다 광범위한 듯 하다.

     

    결국 다른 명령어는 없을까 하고 찾다가 ffmpeg -i output.aac -i output2.mp4  -c copy out.mp4 으로 합칠 수 있다는 말을 찾았다.[각주:2] 이렇게 만들어진 파일을 보니 영상과 소리는 확실히 나온다.

     

    D:>fffmpeg -i output.aac -i output2.mp4  -c copy out.mp4

     

    frame= 3722 fps=0.0 q=-1.0 size=   10240kB time=00:02:32.04 bitrate= 551.7kbits/
    frame= 8654 fps=8465 q=-1.0 size=   26368kB time=00:05:16.43 bitrate= 682.6kbits

     

    ...

     

    frame=150000 fps=7242 q=-1.0 Lsize=  415606kB time=01:23:47.96 bitrate= 677.1kbi
    ts/s speed= 243x
    video:333273kB audio:79727kB subtitle:0kB other streams:0kB global headers:0kB m
    uxing overhead: 0.630830&

    이제 파일이 하나가 되었다.

     

    싱크 맞추기

    드디어 파일을 하나로 만든 후, 동영상을 재생시켜봤는데... 싱크가 안맞다. 오디오 파일이 1,2초도 아닌 28초 씩이나 빠르다. 파일 몇개가 설마 덜받아 졌나? 그런데 다운로드 프로그램에 에러는 없었는데? 뭐가 문제인지는 모르겠지만, 우선 싱크를 맞춰야 했다.

     

    오디오 편집 프로그램으로 빈 사운드를 추가해야하나? 아니면 에프터 이펙트 같은 영상 편집프로그램으로 새로 인코딩 하는게 나을려나? 라고 생각했는데, 인터넷을 찾아보니 mp4 파일 자체에 딜레이(오프셋)을 기록하는 방법이 있다는 것을 찾았다.[각주:3]  별도의 인코딩 없이 딜레이를 넣을 수 있다니 다행이다.

     

    명령어는 비디오에 딜레이를 주는 방법으로

    ffmpeg.exe -i "out.mp4" -itsoffset 시간 -i "out.mp4" -map 1:v -map 0:a -c copy "movie-video-delayed.mp4"

    를 사용하면 됐다. 나의 경우에는 비디오가 28초 느리므로 시간에 -28을 넣었다.

     

    재생을 해보니 역시 문제없이 재생됐다. 싱크도 잘 맞는다.

     

    5시간에 걸쳐 1시간 20분 동영상을 뽑아냈다.

     

    여담

    무설치로 동영상 인코딩, 자르기, 합치기 하는데 아무런 문제도 없고 심지어 스트리밍까지 가능한 만능 프로그램. FFmpeg는 참 대단한 것 같다. 어쩌면 최고의 오픈 소스 프로그램 중 하나.

     

     

    [본문에 사용된 SVG 파일]

    FFmpeg_Logo_new.svg



    1. ffmpeg -i output.aac -c copy output2.m4a [본문으로]
    2. https://stackoverflow.com/questions/41247543/ffmpeg-mux-video-and-audio-and-trim-the-audio 를 조금 변형 [본문으로]
    3. https://superuser.com/questions/982342/in-ffmpeg-how-to-delay-only-the-audio-of-a-mp4-video-without-converting-the-au [본문으로]

    댓글

어제는 이곳에 명이 다녀갔습니다.

Powered & Designed by Tistory