자르기 및 크기 조정을 통해 비디오를 고정 화면 크기로 변환


22

나는 이것을 스스로 알아 내려고 노력했지만 수많은 옵션이 나를 방해합니다.

들어오는 비디오를 고정 화면 크기로 변환 하기 위해 이상적으로 ffmpeg또는 mencoder다른 것을 사용하고 싶습니다 .

비디오가 더 넓거나 짧으면 비디오를 가운데로 자릅니다. 올바른 크기가 아닌 경우 크기를 조정하여 화면 크기를 정확히 고정하십시오.

마지막으로 필요한 것은 MP3 오디오 트랙이있는 XVid AVI에서 720x480입니다.

최대 해상도로 크기를 조정하는 방법을 보여주는 많은 페이지를 찾았지만 비디오가 정확히 그 해상도가되어야합니다 (추가 부품이 잘리고 검은 막대가 없음).

누구나 나에게 명령 줄을 알려 줄 수 있습니까? 아니면 적어도 거기에서 어떤 방법으로도 갈 수 있습니까? 여러 명령 줄이 필요한 경우 (해상도를 얻으려면 X를 실행 하고이 계산을 수행 한 다음 해당 계산의 출력으로 Y를 실행하십시오) 스크립트를 작성할 수 있습니다.


분명히 비디오 장치는 Xegid AVI뿐만 아니라 Mpeg4에서도 작동합니다.
Andy Jeffries

답변:


19

나는 ffmpeg 전문가가 아니지만 이것이 트릭을해야합니다.

우선 다음과 같이 입력 비디오의 크기를 얻을 수 있습니다.

ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=height,width in.mp4

최근의 ffmpeg를 사용하면 다음 옵션을 사용하여 비디오 크기를 조정할 수 있습니다.

ffmpeg -i in.mp4 -vf scale=720:480 out.mp4

가로 세로 비율을 유지하면서 비디오의 크기를 조정 -1하기 위해 너비 또는 높이를 설정할 수 있습니다 ffmpeg. 실제로 -2계산 된 값이 짝수 여야하기 때문에 더 나은 선택입니다. 따라서 다음을 입력 할 수 있습니다.

ffmpeg -i in.mp4 -vf scale=720:-2 out.mp4

비디오를 얻을 후에는 예상보다 클 수 있습니다 720x480당신이 할 수 있기 때문에 ffmpeg당신이 그것을 잘라해야합니다, 그래서 높이를 계산한다. 이것은 다음과 같이 수행 할 수 있습니다 :

ffmpeg -i in.mp4 -filter:v "crop=in_w:480" out.mp4

마지막으로 다음과 같은 스크립트를 작성할 수 있습니다 (쉽게 최적화 할 수 있지만 가독성을 위해 단순하게 유지했습니다).

#!/bin/bash

FILE="/tmp/test.mp4"
TMP="/tmp/tmp.mp4"
OUT="/tmp/out.mp4"

OUT_WIDTH=720
OUT_HEIGHT=480

# Get the size of input video:
eval $(ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=height,width ${FILE})
IN_WIDTH=${streams_stream_0_width}
IN_HEIGHT=${streams_stream_0_height}

# Get the difference between actual and desired size
W_DIFF=$[ ${OUT_WIDTH} - ${IN_WIDTH} ]
H_DIFF=$[ ${OUT_HEIGHT} - ${IN_HEIGHT} ]

# Let's take the shorter side, so the video will be at least as big
# as the desired size:
CROP_SIDE="n"
if [ ${W_DIFF} -lt ${H_DIFF} ] ; then
  SCALE="-2:${OUT_HEIGHT}"
  CROP_SIDE="w"
else
  SCALE="${OUT_WIDTH}:-2"
  CROP_SIDE="h"
fi

# Then perform a first resizing
ffmpeg -i ${FILE} -vf scale=${SCALE} ${TMP}

# Now get the temporary video size
eval $(ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=height,width ${TMP})
IN_WIDTH=${streams_stream_0_width}
IN_HEIGHT=${streams_stream_0_height}

# Calculate how much we should crop
if [ "z${CROP_SIDE}" = "zh" ] ; then
  DIFF=$[ ${IN_HEIGHT} - ${OUT_HEIGHT} ]
  CROP="in_w:in_h-${DIFF}"
elif [ "z${CROP_SIDE}" = "zw" ] ; then
  DIFF=$[ ${IN_WIDTH} - ${OUT_WIDTH} ]
  CROP="in_w-${DIFF}:in_h"
fi

# Then crop...
ffmpeg -i ${TMP} -filter:v "crop=${CROP}" ${OUT}

나는 시나리오를 놓칠 것이라는 재미있는 느낌을 가지고 있었지만 많은 비디오 파일로 시도했지만 비디오를 절대적으로 정확한 크기로 자르고 크기를 조정하는 것처럼 보입니다.
Andy Jeffries

CROP_SIDE 결정에 문제가있는 것 같습니다.
Sutra

`# 실제 크기와 원하는 크기 사이의 비율을 얻습니다. w_rate = echo "scale=3; ${in_width}/${out_width}*1000"| bc | awk '{printf "%d", $0}' h_rate = echo "scale=3; ${in_height}/${out_height}*1000"| bc | awk '{printf "%d", $0}' # 짧은 쪽을 찍어서 비디오가 최소한 원하는 크기만큼 커지고 더 긴 쪽을 자릅니다 : crop_side = 'n'if [$ {w_rate} -gt $ {h_rate}]; 다음 규모 = "- 2 : $ {out_height}"다른 규모의 'w'crop_side = "$ {out_width} : - 2"crop_side = 'H'파이 '
수트라

23
ffmpeg -i input.file -vf "scale=(iw*sar)*max(720/(iw*sar)\,480/ih):ih*max(720/(iw*sar)\,480/ih), crop=720:480" -c:v mpeg4 -vtag XVID -q:v 4 -c:a libmp3lame -q:a 4 output.avi

"input.file"을 입력 파일 이름으로 바꾸십시오.


ffprobe에 대한 호출이 필요하지 않기 때문에 이것이 최고의 답변입니다. 명령에서 백 슬래시 쉼표 시퀀스를 확인하십시오. C / JavaScript / PHP 문자열에 명령을 배치하는 경우 백 슬래시를 이스케이프해야합니다.
cleong

잘 했어, 브라이언 비디오 필터 부분도 내가 필요한 것입니다. (즉, 오래된 4 : 3 비디오를 16 : 9로 변환)!
Dave

1
천재! 모두 하나에서 이루어집니다.
Soli

2
위의 스크립트보다 훨씬 깨끗합니다. XVID / MP3을 원하지 않으면 두 번째 따옴표 뒤에있는 태그를 다음과 같이 변경할 수 있습니다.-c:a copy scaled_result.mp4
Nick

7

한 번에 자르고 크기를 조정하려면 다음과 같이 자르기 후 규모의 필터 체인을 만들 수 있습니다.

ffmpeg -i SomeInput.mp4 -vf "crop=in_h*9/16:in_h,scale=-2:400" -t 4 SomeOutput.mp4

위의 첫 번째 비디오는 16 : 9 세로로 비디오를 자른 다음 400px 높이 x 적절한 (짝수) 너비로 조정합니다.


1

나는 ffmpeg를 처음 사용하지만 이제는 VB.NET에서 멋진 작은 변환기를 사용하여 SD 카드에 액세스 할 수 있지만 복잡한 비디오를 디코딩하기에는 충분한 전원이없는 작은 장치에서 사용할 수있는 다양한 출력 형식의 원시 동영상을 만듭니다.

크기를 조정하고자를 때 작동하는 방식 때문에 수동으로 코딩하고 매개 변수를 작성해야했습니다. 기본적으로 결과 너비와 높이를 알아야합니다.

옵션에 대한 2 개의 확인란이 있습니다 :-

종횡비 유지 (X) 모든 픽셀 채우기 (X)

입력으로 4 개의 변수 만 필요합니다. (1) 원본 비디오 너비, (2) 원본 비디오 높이, (3) 장치 너비, (4) 장치 높이.

VB.NET의 경우 어떤 언어에도 쉽게 적용 할 수 있습니다.

    Dim crop As String = "" ' will build this in ffmpeg format for -s or scale and crop

    If cbAspectRatio.Checked = False Then
        m_dest_output_w = sz._w
        m_dest_output_h = sz._h

        ' scale to w * h - simple
        crop = " -s " & m_dest_output_w & ":" & m_dest_output_h
    Else
        Dim ratio As Double = CDbl(m_video_width) / CDbl(m_video_height) ' this is aspect ratio of original unsized video

        If cbFillPixels.Checked = False Then ' shrink to fit
            If sz._w * ratio <= m_video_height Then
                m_dest_output_w = sz._w
                m_dest_output_h = sz._w / ratio
            Else
                m_dest_output_h = sz._h
                m_dest_output_w = sz._h / ratio
            End If

            ' no cropping just resizing to a non-filled area that fits

            crop = " -s " & m_dest_output_w & ":" & m_dest_output_h ' no cropping needed as letterboxed

        Else ' expand / fill --- cropping needed
            If sz._w * ratio >= m_video_height Then
                m_dest_output_w = sz._w
                m_dest_output_h = sz._w * ratio

                crop = ",crop=" & sz._w & ":" & sz._h & ":0:" & Math.Abs((m_dest_output_h - sz._h)) \ 2
            Else
                m_dest_output_h = sz._h
                m_dest_output_w = sz._h * ratio

                crop = ",crop=" & sz._w & ":" & sz._h & ":" & Math.Abs((m_dest_output_w - sz._w)) \ 2 & ":0"
            End If

            crop = " -vf scale=" & m_dest_output_w & ":" & m_dest_output_h & crop

            m_dest_output_w = sz._w
            m_dest_output_h = sz._h
        End If
    End If
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.