반응형

동영상에 자막을 인코딩 해 보자.

 

● 조금 자세한 자막 인코딩 명령

ffmpeg -i LoveStory.mp4 -vf "subtitles='LoveStory.srt':force_style='FontSize=24,PrimaryColour=&HFFFFFF&, BorderStyle=1, Outline=1'" -c:a aac -b:a 160k -c:v libx265 -crf 24 -preset veryfast output.mp4

 

● 옵션 생략
ffmpeg -i LoveStory.mp4 -vf "subtitles='LoveStory.srt':force_style='FontSize=24,PrimaryColour=&HFFFFFF&, BorderStyle=1, Outline=1'" output.mp4

 

● 간단한 옵션 설명
-i = 소스 파일 지정
-c:a aac = 오디오 코덱을 aac로 지정, copy 로 지정하면 기존 오디오 코덱 유지(빠름)
-c:v libx265 = 비디오 코덱을 h.265로 지정, copy 로 지정하면 기존 비디오 코덱 유지(빠름)
-b:a = 오디오 비트레이트. 128k가 기본
-b:v = 비디오 비트레이트. 128k가 기본
-preset = 압축률과 시간을 설정한다. fast, medium, slow등 여러가지.
-crf = 화질을 결정. 0~59. 0이 무손실.
-vf = 필터 그래프를 생성하고 스트림 필터로 사용. 이걸로 자막을 지정. (Filtering)
필터의 자막 부분은 FFmpeg Filters Documentation 에서 4.1 Filtergraph syntax, 11.249 subtitles 참고.

 

아래 링크의 문서 중 5번이 옵션에 관한 전체적인 설명이다.

ffmpeg Documentation

 

● 간단 지정
ffmpeg -i LoveStory.mp4 -vf subtitles=LoveStory.srt output.mp4

 

smi 자막은 지원하지 않는다. srt를 사용하자.

 

※ 참고 자료

FFmpeg_Book.z01
19.53MB
FFmpeg_Book.zip
2.84MB

 

2.230에 자막 관련 내용이 있다.

 

 

이번엔 동영상에서 자막을 추출해 보자.

 

● 명령

ffmpeg -i topgun.mkv sub.srt

특별한 옵션 없이 사용하면 영상에서 첫 번째 자막을 추출한다.

 

ffmpeg -i topgun.mkv -map 0:3 sub.srt

-map 0:4 = 4번째 스트림의 데이터를 추출한다. 자막이 여러개인 경우 두 번째 자막이 3. (보통 0 = Video, 1 = Audio, 2 부터 자막이다)

두 번째 자막 추출 시 -map 0:3 대신 -map s:1로 해도 된다. (s:0 = 첫 번째 자막, s:1 = 두 번째 자막)

 

자막 중에서도 실행 시 subrip (srt)로 표시되면 문제없이 추출되지만 hdmv_pgs_subtitle (pgssub)로 표시되는 자막을 추출하려 하면 아래와 같은 에러가 발생한다. (srt는 텍스트 데이터지만 pgs는 알파 채널이 포함된 비트맵 데이터 자막이다. 영상위에 비트맵으로 된 자막을 그리는 것이다.)
Subtitle encoding currently only possible from text to text or bitmap to bitmap

아래 명령어로 추출은 가능하지만 sub.sup파일은 다른 OCR 프로그램을 이용해 텍스트 파일로 변환해야 한다.

ffmpeg -i topgun.mkv -map 0:4 -c copy sub.sup

 

ffmpeg -i topgun.mkv -vn -an -c:s copy -map s:0 sub.srt 명령도 첫 번째 자막을 추출한다.

-vn = 비디오 스트림을 차단한다.

-an = 오디오 스트림을 차단한다.

-sn = 자막 스트림을 차단한다.

 

● 아래와 같은 파이썬 명령으로도 자막을 추출할 수 있다.

import ffmpeg
input = ffmpeg.input('topgun.mkv').output('sub.srt', map='s:0').run(quiet=True)

ffmpeg-python

 

● 2초에 영상 한 프레임 추출하기

ffmpeg -ss 0:02 -i video.mp4 -frames:v 1 -update 1 pic.png

-ss 옵션을 -i 앞에 넣으면 파이프라인의 디코딩 과정을 생략하기 때문에 훨씬 빠르다.

import ffmpeg
input = ffmpeg.input('video.mp4').output('pic.png', ss='0:02', frames=1, update=1).run(quiet=True)

파이썬에서는 위와 같이 해도 빠르다.

 

반응형

'FFmpeg' 카테고리의 다른 글

FFmpeg RTSP IP Camera 영상 저장  (0) 2025.03.14
Posted by J-sean
:
반응형

서버에서 데이터를 받아 오는 경우 모든 문자가 알파벳이나 숫자라면 상관 없지만 한글이 섞여 있다면 글자가 깨지는 문제가 발생하고 어떤 인코딩이 사용되었는지 확인하기 어려운 경우가 있다. 아래와 같이 단순한 방법으로 간단히 확인 할 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
try {
    Log.d("Encoding Check""utf-8 -> euc-kr: " + new String(str.getBytes("utf-8"), "euc-kr"));
    Log.d("Encoding Check""utf-8 -> ksc5601: " + new String(str.getBytes("utf-8"), "ksc5601"));
    Log.d("Encoding Check""utf-8 -> x-windows-949: " + new String(str.getBytes("utf-8"), "x-windows-949"));
    Log.d("Encoding Check""utf-8 -> iso-8859-1: " + new String(str.getBytes("utf-8"), "iso-8859-1"));
 
    Log.d("Encoding Check""iso-8859-1 -> euc-kr: " + new String(str.getBytes("iso-8859-1"), "euc-kr"));
    Log.d("Encoding Check""iso-8859-1 -> ksc5601: " + new String(str.getBytes("iso-8859-1"), "ksc5601"));
    Log.d("Encoding Check""iso-8859-1 -> x-windows-949: " + new String(str.getBytes("iso-8859-1"), "x-windows-949"));
    Log.d("Encoding Check""iso-8859-1 -> utf-8: " + new String(str.getBytes("iso-8859-1"), "utf-8"));
 
    Log.d("Encoding Check""euc-kr -> utf-8: " + new String(str.getBytes("euc-kr"), "utf-8"));
    Log.d("Encoding Check""euc-kr -> ksc5601: " + new String(str.getBytes("euc-kr"), "ksc5601"));
    Log.d("Encoding Check""euc-kr -> x-windows-949: " + new String(str.getBytes("euc-kr"), "x-windows-949"));
    Log.d("Encoding Check""euc-kr -> iso-8859-1: " + new String(str.getBytes("euc-kr"), "iso-8859-1"));
 
    Log.d("Encoding Check""ksc5601 -> euc-kr: " + new String(str.getBytes("ksc5601"), "euc-kr"));
    Log.d("Encoding Check""ksc5601 -> utf-8: " + new String(str.getBytes("ksc5601"), "utf-8"));
    Log.d("Encoding Check""ksc5601 -> x-windows-949: " + new String(str.getBytes("ksc5601"), "x-windows-949"));
    Log.d("Encoding Check""ksc5601 -> iso-8859-1: " + new String(str.getBytes("ksc5601"), "iso-8859-1"));
 
    Log.d("Encoding Check""x-windows-949 -> euc-kr: " + new String(str.getBytes("x-windows-949"), "euc-kr"));
    Log.d("Encoding Check""x-windows-949 -> utf-8: " + new String(str.getBytes("x-windows-949"), "utf-8"));
    Log.d("Encoding Check""x-windows-949 -> ksc5601: " + new String(str.getBytes("x-windows-949"), "ksc5601"));
    Log.d("Encoding Check""x-windows-949 -> iso-8859-1: " + new String(str.getBytes("x-windows-949"), "iso-8859-1"));
catch(Exception e) {
    e.printStackTrace();
}



Logcat을 확인해 보면 'iso-8859-1 -> utf-8'이 정상적으로 한글을 표시했다.


그런데 위 코드 중 'utf-8 -> iso-8859-1'은 Logcat에 출력 되지 않는다. System.out.println()으로 해도 출력되지 않지만, 이 문자열을 기기에서 출력해 보면 깨진 한글로 표시는 된다. 이유는 알 수 없다.

1
    Log.d("Encoding Check""utf-8 -> iso-8859-1: " + new String(str.getBytes("utf-8"), "iso-8859-1"));



반응형
Posted by J-sean
: