정적 크기의 플레이어에 맞게 ffmpeg / avconv를 사용하여 비디오 크기 조정


65

폭 700px, 높이 400px 인 html 5 비디오 플레이어가 있습니다. 내가 사용하려고 해요 avconv(가로 세로 비율을 유지하면서)과 내 플레이어에 맞는 확인하고 크기를 조정할 수는 FFmpeg을 사용합니다.

입력은 모든 크기의 파일이 될 수 있으므로 더 큰 파일의 크기를 조정해야하지만 더 작은 파일의 크기를 검은 막대로 가운데에 맞 춥니 다. 지금까지 시도한 결과 : -s및 -aspect, 스위치 pad와 함께 사용되는 것을 보았지만 -vf필요한 것을 얻을 수있는 방법을 이해하지 못했습니다.

이미지

이것은 내가 필요한 것에 대한 대략적인 아이디어입니다. 그것이 가능한지 잘 모르겠습니다. CSS의 최대 너비 / 최대 높이와 ​​거의 같습니다. 나는 이것이 혼란스러운 단어 일 수 있음을 알고 있지만 누군가 내가 말하는 것을 이해하면 도움을 주셔서 감사합니다. 감사합니다.

avconv 명령 :

avconv -y -i control.avi -vcodec libx264 -b 2000k -bufsize 20M -acodec aac -strict experimental -ar 44100 -ab 256k bigbuck_out.mp4


4
나중에 답변을 드리겠습니다. 그러나 다음을 언급 할 것이라고 생각했습니다. 고정 기둥 또는 레터 박스를 추가하기 위해 비디오를 다시 인코딩하는 것은 끔찍한 아이디어입니다. 해당 프로세스에서 품질이 떨어지거나 파일 크기가 불필요하게 증가 할뿐만 아니라 나중에 막대를 제거 할 수 없게됩니다. 이상적으로 플레이어는 간단히 처리하고 비디오를 표시하는 동안 크기를 조정해야합니다. 요청하면 유스 케이스는 무엇입니까?
— slhck

우리는 S3 버킷에 원본 파일을 숨기므로 아무런 문제가 없으며 다양한 비디오 유형을 허용하므로 어쨌든 다시 인코딩하고 있습니다.이 모든 파일은 스트리밍에 적합한 h.264 mp4 파일로 끝나야합니다 브라우저. 비디오의 크기를 조정 한 다음 html / css 기둥 / 레터 박스를 만드는 것이 좋습니다. 감사합니다
— Jamie Taylor

1
수락 된 답변의 소유자로서 나는 내 게시물을 수락하지 말고 대신 가장 최근의 훨씬 간단한 LordNeckbeard의 답변을 수락 할 것을 제안합니다.
— slhck

@slhck, 나는 당신의 축복과 함께 그것을 고려하고 있었다, 나는 그렇게 할 것이다.
— Jamie Taylor

답변:


52

간단한 방법은 스케일 필터force_original_aspect_ratio 에서 옵션 을 사용하는 것입니다 .

원본 이미지
원본 이미지. 640x480, 4 : 3 종횡비 비디오를 나타냅니다.

이 예에서 원본 이미지는 원래 종횡비를 유지하면서 16 : 9 종횡비 출력에 맞게 조정됩니다. 이렇게하려면 다음 중 하나를 수행하십시오.

필라 박스 또는 레터 박스

필러 박스 이미지
필라 박스 이미지. 640x480 (4 : 3) 입력을 1280x720 (16 : 9) 출력에 장착

ffmpeg -i input -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" output
  • 이미지가 확대됩니다. 업 스케일링을 피하려면 아래 예를 참조하십시오.

  • 입력 종횡비가 출력 종횡비보다 넓은 경우 레터 박스가 대신 발생합니다. 예를 들어, 16 : 9 출력에 맞는 2.35 : 1 종횡비의 입력은 레터 박스를 생성합니다.

위와 동일하지만 업 스케일링 없음

업 스케일링 없음
업 스케일링없이 1280x720 (16 : 9) 출력으로 640x480 (4 : 3) 입력.

ffmpeg -i input -vf "scale='min(1280,iw)':min'(720,ih)':force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" output

수확고

여기에 이미지 설명을 입력하십시오
자른 이미지. 4 : 3 입력 화면비, 16 : 9 출력 화면비.

ffmpeg -i input -vf "scale=1280:720:force_original_aspect_ratio=increase,crop=1280:720" output

그리고 빈 채우기를 추가하려면?
— Tiago Ferezin

@TiagoFerezin "빈 채우기"란 무엇입니까?
— llogan

죄송합니다. 예를 들어 검정 대신 다른 색으로
— 채 웁니다.

2
@TiagoFerezin 아, 그렇습니다. 하기 쉽다. 패드 필터를 사용하는 예에서는 다음 color과 같은 옵션을 추가 할 수 있습니다 pad=1280:720:(ow-iw)/2:(oh-ih)/2:color=red(또는 원하는 경우 16 진수를 사용할 수 있음). 색상 목록을 참조하십시오 .
— llogan

61

고정 출력 너비에 필라 또는 레터 박스를 추가하는 명령은 다음과 같습니다. 시간이 오래 걸리지 만 패딩을 지정해야합니다.

먼저, 쉘에서 출력 너비와 높이를 정의하십시오.

width=700
height=400

그런 다음 명령을 실행하십시오.

ffmpeg -i in.mp4 -filter:v "scale=iw*min($width/iw\,$height/ih):ih*min($width/iw\,$height/ih), pad=$width:$height:($width-iw*min($width/iw\,$height/ih))/2:($height-ih*min($width/iw\,$height/ih))/2" out.mp4

크기와 크기를 조정하는 데 필요한 기본 요소로 요약되어 있습니다. 다른 비디오 및 오디오 옵션을 원하는대로 추가하십시오. 의 번호를 참고 width하고 height대부분의 코덱을 위해 일하기 위해 2로 나눌 수있다.

진행 상황에 대한 설명은 다음과 같습니다.

  • 스케일링 :
    • 먼저 너비 또는 높이를 기준으로 스케일링할지 여부를 파악해야합니다.
    • 이를 위해 출력 너비를 입력 너비로 나누고 출력 높이를 입력 높이로 나눕니다. 이것은 우리에게 각 차원의 스케일 팩터를 줄 것입니다.
    • 그런 다음 어느 쪽이 더 낮은 지 확인하고 (와 함께 min()) 크기 조정을 위해 해당 요소 만 선택합니다.
    • 마지막으로 입력 너비와 높이에 해당 계수 ( iw*min(…):ih*min(…))를 곱합니다 .
  • 심:
    • $width:$height 출력 너비와 높이
    • 결과 비디오를 배치 할 위치를 파악하려면 최대 출력 너비에서 배율을 조정하고 최대 출력 높이에서 배율을 빼야합니다.
    • 스케일 된 너비와 높이는 scale필터 의 표현식입니다 .
    • 결과 오프셋을 2로 나누면 양쪽에 테두리가 추가됩니다.

3
@JamieTaylor -movflags +faststartslhck의 예를 추가해보십시오 . 점진적으로 다운로드 한 비디오가 완전히 다운로드되기 전에 재생을 시작할 수있게하며, 자세한 인코딩 지침 및 예 는 FFmpeg 및 x264 인코딩 안내서 및 FFmpeg 및 AAC 인코딩 안내서 를 참조하십시오.
— llogan

패드 필터를 짧게 만들 수 있습니다.pad=$width:$height:(ow-iw)/2:(oh-ih)/2"
— jdi

1
@jdi 다운 스케일링하는 경우 작동하지 않습니다 ow-iw. 음수 값이됩니다 .
— slhck

출발점 감사합니다! 그러나 샘플 종횡비가! = 1 인 동영상에 적절한 종횡비를 얻으려면 모든 "iw"발생에 "sar"를 곱해야합니다. "iw"의 모든 발생을 "(sar * iw)"로 바꾸십시오. 필터 표현에서 나를 위해 작동합니다.
— schieferstapel

@ slhck 이봐, 안드로이드에서 노력하고 있지만 작동하지 않는 것 같습니다. ffmpeg -i 입력 .mp4-필터 : v 스케일 = 640 * 분 (700 / 640,400 / 360) : 360 * 분 (700 / 640,400 / 360), 패드 = 700 : 400 : (700-640 * 분 (700 / 640,400) / 360)) / 2 : (400-360 * min (700 / 640,400 / 360)) / 2
— 출력 mp4

8

세 단계 로이 작업을 수행해야합니다.

  1. 입력 종횡비 확인
  2. DAR> 너비가 7/4 인 비디오의 크기를 조정하고 (가로 세로 비율을 유지하기 위해 너비를 700으로 변경하고 높이의 크기를 조정) DAR <7/4의 높이를 가진 비디오의 크기를 조정하십시오
  3. 비디오를 700 : 400 공간에 맞도록 채 웁니다.

FFmpeg / avconv는 한 번의 트랜스 코딩으로 비디오 필터를 사용하여 스케일링 / 패딩을 한 번만 수행 할 수 있습니다. 예를 들어 16 : 9 비디오를 찍으려면 가로 방향으로 크기를 조정 한 다음 결과를 레터 박스로 지정하십시오.

ffmpeg -i input.avi -filter:v 'scale=700:-1,pad=700:400:(ow-iw)/2:(oh-ih)/2' \
-c:v libx264 -b:v 2000k -bufsize 20M -c:a aac -strict experimental -ar 44100 -b:a 256k output.mp4

...하지만 첫 번째 단계 (가로 세로 비율 감지 및 필요한 7 : 4와 비교)에는 일종의 스크립트를 사용해야합니다.

ffprobe input.avi 2>&1 | sed -n '/Video:/s/.*DAR \([0-9]*:[0-9]*\)].*/\1/p'

... '16 : 9'또는 '4 : 3'과 같은 비디오의 종횡비를 얻을 수 있습니다. bash 스크립트에서는 다음과 같은 것을 사용합니다.

#!/bin/bash

##  Get the aspect ratio in the form x/y
dar=$(ffprobe test0.mp4 2>&1 | sed -n '/Video:/s/.*DAR \([0-9]*:[0:9]*\)].*/\1/p' | sed 's|:|/|')
##  use bc to do x/y*100 (bash can't handle floats)
DAR=$(bc <<< 'scale=2; $dar*100')

##  ${DAR%.00} will remove the trailing .00 left by bc
if [ ${DAR%.00} -ge 175 ]; then
    ffmpeg -i "$1" -filter:v 'scale=700:-1,pad=700:400:(ow-iw)/2:(oh-ih)/2' \
    -c:v libx264 -b:v 2000k -bufsize 20M -c:a aac -strict experimental -ar 44100 -b:a 256k "${1%.*}.mp4
else
    ffmpeg -i "$1" -filter:v 'scale=-1:400,pad=700:400:(ow-iw)/2:(oh-ih)/2' \
    -c:v libx264 -b:v 2000k -bufsize 20M -c:a aac -strict experimental -ar 44100 -b:a 256k "${1%.*}.mp4
fi

exit 0

분명히 당신은 당신의 요구에 맞게 그것을 조정해야합니다.


1
그래도 한 단계로 그렇게 할 수 있습니다. 내 대답을 참조하십시오.
— slhck

@slhck 이제 쉬워졌습니다. 기타 숭어와 답변을 참조하십시오.
— llogan

@LordNeckbeard 감사합니다! 나는 최근에 그 옵션을 보았고 실제로 훨씬 쉬워졌습니다.
— slhck
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.