Thay đổi kích thước video với ffmpeg / avconv để phù hợp với trình phát kích thước tĩnh


65

Tôi có trình phát video html 5 rộng 700px, cao 400px. Tôi đang cố gắng sử dụng avconvđể sử dụng ffmpeg để thay đổi kích thước (trong khi vẫn giữ tỷ lệ khung hình) và đảm bảo nó phù hợp với trình phát của tôi.

Đầu vào có thể là một tệp có kích thước bất kỳ, vì vậy tôi cần thay đổi kích thước những cái lớn hơn nhưng tập trung vào những cái nhỏ hơn bằng các thanh màu đen. Cho đến nay tôi đã thử: -s-aspect, tôi đã thấy padđược sử dụng với công -vftắc nhưng không hiểu làm thế nào nó hoạt động đủ để có được những gì tôi cần.

Hình ảnh

Đây là một ý tưởng sơ bộ về những gì tôi cần. Tôi không chắc liệu nó có khả thi hay không. Nó gần giống như chiều rộng tối đa / chiều cao tối đa của CSS. Tôi nhận ra điều này có thể chỉ là một mớ bòng bong trong lời nói nhưng nếu có ai đó hiểu tôi đang nói gì, tôi sẽ đánh giá cao sự giúp đỡ, Cảm ơn.

lệnh avconv:

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


4
Tôi sẽ viết một câu trả lời sau, nhưng tôi nghĩ tôi đã đề cập đến vấn đề sau: Mã hóa lại video chỉ để thêm trụ cột cố định- hoặc hộp thư là một ý tưởng tồi. Bạn không chỉ mất chất lượng trong quá trình đó (hoặc tăng kích thước tệp một cách không cần thiết), bạn cũng sẽ không thể thoát khỏi các thanh sau này. Lý tưởng nhất là trình phát của bạn chỉ cần quan tâm đến điều đó và thay đổi kích thước video trong khi hiển thị nó. Trường hợp sử dụng của bạn là gì nếu tôi có thể yêu cầu?
slhck

Chúng tôi bỏ tập tin gốc vào nhóm S3, vì vậy không có vấn đề gì và dù sao chúng tôi cũng mã hóa lại vì chúng tôi chấp nhận một phạm vi rộng các loại video, tất cả những điều này phải kết thúc dưới dạng tệp h.264 mp4 phù hợp để phát trực tuyến một trình duyệt. Vì vậy, bạn đề nghị thay đổi kích thước video và sau đó tạo cột / hộp thư html / css? Cảm ơn
Jamie Taylor

1
Là chủ sở hữu của câu trả lời được chấp nhận, tôi đề nghị bạn không chấp nhận bài đăng của tôi và chấp nhận câu trả lời của LordNeckbeard, vì đây là câu trả lời gần đây nhất và đơn giản hơn nhiều.
slhck

@slhck, tôi đã xem xét nó, với phước lành của bạn, tôi sẽ làm cho nó như vậy.
Jamie Taylor

Câu trả lời:


52

Một phương pháp đơn giản là sử dụng force_original_aspect_ratiotùy chọn trong bộ lọc tỷ lệ .

ảnh gốc
Ảnh gốc. Đại diện cho video tỷ lệ khung hình 640x480, 4: 3.

Trong các ví dụ này, hình ảnh gốc sẽ được thu nhỏ để phù hợp với đầu ra tỷ lệ khung hình 16: 9 trong khi vẫn giữ tỷ lệ khung hình gốc. Để làm điều này, bạn có thể:

Trụ cột hoặc hộp thư

hình ảnh trụ cột
Hình ảnh trụ cột. Lắp đầu vào 640x480 (4: 3) vào đầu ra 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
  • Điều này sẽ nâng cao hình ảnh. Nếu bạn muốn tránh nâng cấp, xem ví dụ dưới đây.

  • Thay vào đó, hộp thư sẽ xảy ra nếu tỷ lệ khung hình đầu vào rộng hơn tỷ lệ khung hình đầu ra. Ví dụ: đầu vào có tỷ lệ khung hình 2,35: 1 phù hợp với đầu ra 16: 9 sẽ dẫn đến hộp thư.

Tương tự như trên nhưng không nâng cấp

không nâng cấp
640x480 (4: 3) đầu vào thành đầu ra 1280x720 (16: 9) mà không cần nâng cấp.

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

Mùa vụ

nhập mô tả hình ảnh ở đây
Cắt ảnh. Tỷ lệ khung hình đầu vào 4: 3, tỷ lệ khung hình đầu ra 16: 9.

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

Và cho tôi để thêm một điền vào chỗ trống?
Tiago Ferezin

@TiagoFerezin "Điền vào chỗ trống" là gì?
llogan

ồ xin lỗi, tô màu khác thay vì màu đen, ví dụ
Tiago Ferezin

2
@TiagoFerezin À, vâng. Dễ làm. Trong các ví dụ sử dụng bộ lọc pad, bạn có thể thêm colortùy chọn, chẳng hạn như pad=1280:720:(ow-iw)/2:(oh-ih)/2:color=red(hoặc bạn có thể sử dụng hệ thập lục phân nếu bạn thích). Xem danh sách màu sắc .
llogan

61

Đây là lệnh sẽ thêm trụ cột hoặc hộp thư cho chiều rộng đầu ra cố định. Đó là một chút dài, nhưng bạn sẽ phải chỉ định phần đệm một cách nào đó.

Đầu tiên, trong shell của bạn xác định chiều rộng và chiều cao đầu ra:

width=700
height=400

Sau đó chạy lệnh:

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

Điều này được loại bỏ các yếu tố cần thiết để thay đổi kích thước và bổ sung thêm các tùy chọn video và âm thanh khác khi bạn thấy phù hợp. Lưu ý rằng các số cho widthheightphải chia hết cho 2 để hoạt động cho hầu hết các codec.

Đây là lời giải thích về những gì đang xảy ra:

  • Chia tỷ lệ:
    • Đầu tiên chúng ta cần tìm hiểu xem nên chia tỷ lệ theo chiều rộng hay chiều cao.
    • Để làm điều này, chúng tôi chia chiều rộng đầu ra cho chiều rộng đầu vào và chiều cao đầu ra cho chiều cao đầu vào. Điều này sẽ cung cấp cho chúng tôi các yếu tố quy mô cho mỗi chiều.
    • Sau đó chúng tôi kiểm tra xem cái nào thấp hơn (với min()) và chỉ chọn yếu tố đó để thay đổi kích thước.
    • Cuối cùng, chúng tôi nhân cả chiều rộng và chiều cao đầu vào với hệ số đó ( iw*min(…):ih*min(…)).
  • Đệm:
    • $width:$height là chiều rộng và chiều cao đầu ra
    • Để tìm ra nơi đặt video kết quả, chúng ta cần trừ chiều rộng được chia tỷ lệ khỏi chiều rộng đầu ra tối đa và chiều cao được chia tỷ lệ từ chiều cao đầu ra tối đa.
    • Chiều rộng và chiều cao được chia tỷ lệ là các biểu thức từ scalebộ lọc.
    • Chúng tôi chia phần bù kết quả cho 2 để thêm viền ở cả hai bên.

3
@JamieTaylor Xem xét thêm -movflags +faststartvào ví dụ của slhck. Nó sẽ cho phép video được tải xuống liên tục của bạn bắt đầu phát lại trước khi nó được tải xuống hoàn toàn, đồng thời xem Hướng dẫn mã hóa FFmpeg và x264Hướng dẫn mã hóa FFmpeg và AAC để biết thêm các hướng dẫn và ví dụ mã hóa.
llogan

Bạn có thể rút ngắn bộ lọc pad thành cái này, tôi nghĩ:pad=$width:$height:(ow-iw)/2:(oh-ih)/2"
jdi

1
@jdi Điều này sẽ không hoạt động nếu bạn hạ thấp, vì nó sẽ dẫn đến các giá trị âm cho ow-iw.
slhck

Cảm ơn điểm khởi đầu! Tuy nhiên, để có được tỷ lệ khung hình phù hợp cho video có tỷ lệ khung hình mẫu! = 1, mọi lần xuất hiện của "iw" cần được nhân với "sar", vì vậy thay thế MỌI trường hợp "iw" bằng "(sar * iw)" trong biểu thức lọc làm việc cho tôi.
schieferstapel

@slhck Này, tôi đang dùng thử Android nhưng có vẻ như nó không hoạt động, bạn có thể giúp tôi không !!! ffmpeg -i input.mp4 -filter: v scale = 640 * min (700 / 640,400 / 360): 360 * phút (700 / 640,400 / 360), pad = 700: 400: (700-640 * phút (700 / 640,400 / 360)) / 2: (400-360 * phút (700 / 640,400 / 360)) / 2 đầu
ra.mp4

8

Dường như với tôi rằng bạn cần phải làm điều này trong ba bước:

  1. Kiểm tra tỷ lệ khung hình đầu vào
  2. Chia tỷ lệ video có chiều rộng DAR> 7/4 (thay đổi chiều rộng thành 700 và chia tỷ lệ chiều cao để giữ tỷ lệ khung hình) và chia tỷ lệ cho các video có DAR <7/4 chiều cao
  3. Đệm video sao cho vừa với không gian 700: 400.

FFmpeg / avconv có thể thực hiện chia tỷ lệ / đệm với các bộ lọc video trong một bước duy nhất, chỉ chuyển mã một lần. Ví dụ: để quay video 16: 9, hãy chia tỷ lệ theo chiều rộng và sau đó gửi hộp thư kết quả:

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

... nhưng đối với bước đầu tiên (phát hiện tỷ lệ khung hình và so sánh nó với tỷ lệ 7: 4 bạn yêu cầu), bạn sẽ phải sử dụng một loại kịch bản nào đó.

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

... sẽ giúp bạn có tỷ lệ khung hình của video, trông giống như '16: 9 'hoặc' 4: 3 '. Trong tập lệnh bash, tôi sẽ sử dụng một cái gì đó như:

#!/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

Rõ ràng bạn sẽ phải điều chỉnh nó theo nhu cầu của bạn.


1
Có thể làm điều đó trong một bước duy nhất, xem câu trả lời của tôi.
slhck

@slhck Bây giờ thì dễ hơn. Xem câu trả lời với guitar-cá đối.
llogan

@LordNeckbeard Cảm ơn! Gần đây tôi đã thấy tùy chọn đó, làm cho nó thực sự dễ dàng hơn nhiều.
slhck
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.