Cara mengubah framerate video tanpa memasukkan ulang

14

Saya mencoba mengubah framerate dari video MP4 (ini adalah video GoPro 120fps, saya ingin memutarnya pada 30fps untuk efek gerakan lambat).

Saya menggunakan avconv untuk ini:

avconv -i SourceMovie.mp4 -vf setpts=4.0*PTS -r 30 DestMovie.mp4

Secara teknis itu berfungsi, tetapi ia memasukkan ulang film. Selain lambat, ini jelas masalah kualitas. Secara teknis harus ada cara untuk hanya mengatur fps di header video, bagaimana saya bisa mengubahnya? (Alat apa pun selain avconv juga berfungsi.)

EboMike
sumber

Jawaban:

15

MP4Box dapat melakukannya.

Perintah

MP4Box -add SourceMovie.mp4#video -raw 1 -new test

membuat file testdan test_track1.h264. Anda sekarang dapat membuat file mp4 dengan framerate mana saja yang Anda inginkan (30 dalam contoh ini):

MP4Box -add test_track1.h264:fps=30 -new DestMovie.mp4

MP4Box adalah bagian dari gpacpaket, jadi pastikan sudah diinstal.

Mitch
sumber
6
Ini benar-benar tidak langsung, tetapi saya mengerti - Anda harus melakukannya dalam dua langkah. Pertama, ekstrak aliran video secara terpisah sebagai mentah ( MP4Box -add source.mp4#video -raw 1 -new test) dan kemudian simpan sebagai MP4 lagi ( MP4Box -add test_track1.h264:fps=30 -new dest.mp4). Anda dapat menambahkan trek audio juga di sana (melalui #audio).
EboMike
Lebih baik menggunakan -singleopsi untuk perintah pertama. MP4Box -single 1 -raw 1 SourceMovie.mp4hanya membuat satu file, SourceMovie_track1.h264bukan dua.
diversenok
6

Mengubah framerate di header video (wadah) tidak berpengaruh pada videostream (atau audiostream) itu sendiri. Reencoding adalah satu-satunya pilihan.

Aliran video memiliki stempel waktu dan dalam sebagian besar video frame saling bergantung satu sama lain karena kompresi antar bingkai. Beberapa pemain dapat mempercepat dan memperlambat video tetapi tidak dengan perintah yang disematkan atau sesuatu. Tidak ada pemain yang dapat mengubah framerate dengan cepat ketika sebuah perintah kontainer meminta untuk melakukannya. Videofile akan keluar dari spesifikasi (mis. Tidak mengikuti standar) dan 99,9% pemain akan menolak untuk mematuhinya. Sangat tidak mungkin untuk melakukan apa yang Anda inginkan tanpa pengodean ulang. Tentu saja Anda bisa menunggu dengan pengodean ulang hingga langkah terakhir dalam pengeditan Anda.

mereka
sumber
1
Terima kasih thom! Pertanyaan bodoh - mengapa? Apakah setiap frame memiliki stempel waktu yang memaksa pemain untuk memaksakan kecepatan pemutaran tertentu? Saya ingin frame yang sama persis, saya hanya ingin mereka diputar pada tingkat yang berbeda.
EboMike
2
Hai Mike, tidak pertanyaan Anda tidak bodoh, terus terang cara Anda anggap cukup pintar. Saya suka cara berpikir Anda. Saya menambahkan lebih banyak info ke jawaban saya karena terlalu lama untuk meletakkan ini di kotak komentar.
thom
Terima kasih! Itu cukup informatif. Sekarang untuk pengodean ulang - apa cara terbaik untuk melakukannya dengan sesuatu seperti avconv? Saya menggunakan baris perintah di atas, tapi itu menghasilkan kualitas yang mengerikan - saya hampir bisa melihat setiap blokir makro.
EboMike
1
Stempel waktu dalam stream video disimpan dalam wadah, bukan bitstream h.264 mentah itu sendiri, saya pikir. Selama Anda hanya ingin mengubah waktu, tetapi bukan urutan, frame mana yang ditampilkan, Anda tidak perlu transcode, hanya remux. (Dan jika Anda melakukan xcode, dengan perangkat keras yang lebih cepat, Anda akan menggunakan -setel lebih lambat atau sangat lambat untuk mendapatkan kualitas lebih pada bitrate SAMA, alih-alih hanya melempar lebih banyak bit pada masalahnya. Dan gunakan -crf 18 atau sesuatu, bukan ABR)
Peter Cordes
1
Saya tidak tahu bagaimana cara mendapatkan ffmpeg untuk menghasilkan framerate yang berbeda. Sepertinya mkvmerge / mp4box diperlukan, kecuali Anda bisa mendapatkan ffmpeg untuk menghasilkan bitstream .264 mentah, dan kemudian menggunakan opsi fps ke demuxer h.264 (yang memiliki dokumen lengkap, karena bitstream tidak memiliki waktu info, hanya memesan.)
Peter Cordes
3

Jika maksud utama Anda adalah memainkannya dalam gerakan lambat, dan tidak menyimpan file sebagai MP4, Anda dapat menggunakan alat GUI MKVmerge untuk melakukan remux ke dalam wadah Matroska yang dapat dengan mudah mengubah framerate. Remuxing jauh lebih baik daripada reencoding, karena hanya mengubah metadata, dan bukan stream itu sendiri.

Pertama Anda menginstal paket

sudo apt-get install mkvtoolnix-gui

Kemudian Anda memulai GUI MKVmerge. Anda akan dihadapkan pada jendela seperti ini

mkvmerge gui 1

Cukup tekan tombol tambah dan pilih file Anda atau bahkan cukup seret-jatuhkan file ke area "Input file". Pada titik ini Anda harus dapat memilih aliran video di video Anda. Anda juga dapat menghapus aliran lain, karena mereka hanya akan menghalangi.

Setelah Anda memilihnya, Anda akan melihat tab bawah menjadi aktif:

masukkan deskripsi gambar di sini

Ubah ke "Format tindakan spesifik"

masukkan deskripsi gambar di sini

Anda dapat melihat bahwa ada bidang "FPS", di mana Anda dapat memasukkan nilai frame per detik. Sepertinya Anda berencana memperlambat segalanya empat kali, jadi sekitar 7 frame per detik akan menjadi tujuan Anda. Anda juga dapat menggunakan opsi "Regangkan oleh".

Setelah itu Anda tinggal mengubah nama file output (jika mau) dan tekan "Start muxing".

Program akan berjalan dan Anda harus memiliki file Anda.

v010dya
sumber
2

Saya juga ingin memperlambat lossless dari 120 film FPS saya menjadi 30 FPS. Saya membuat skrip yang melakukannya dengan mengubah tempo suara dan memodifikasi FPS langsung dalam wadah MP4. Diperlukan alat berikut:

  1. avconv untuk mengonversi aliran audio
  2. sondstretch untuk memperlambat tempo audio
  3. gpac untuk mendapatkan MP4Box untuk mengubah FPS

Skrip yang digunakan untuk konversi ada di sini:

#!/bin/bash
#########################################
# Lossless slow down from 120 to 30 FPS #
#                                       #
# Use:                                  #
#                                       #
#   slow.bash <mp4_file>                #
#                                       #
#                           #-= OSi =-# #
#########################################


# Prepare basic variables
IN_FILE="$1"
NAME=$(echo "${IN_FILE}" | sed 's/\.[^.]*//')


# Clean up before start
rm -f "${NAME}.ac3" "${NAME}.wav" "${NAME}_.wav" "${NAME}" "${NAME}_track1.h264" "${NAME}_slow.mp4"


# Slow down sound
avconv -i "${IN_FILE}" -vn -acodec pcm_s16le "${NAME}_.wav"
soundstretch "${NAME}_.wav" "${NAME}.wav" -tempo=-75
avconv -i "${NAME}.wav" -vn -codec:a ac3_fixed -b:a 448k "${NAME}.ac3"


# Change video frame rate and multiplex with slowed sound
MP4Box -add "${IN_FILE}#video" -raw 1 -new "${NAME}"
MP4Box -add "${NAME}_track1.h264:fps=30" -add "${NAME}.ac3" -new "${NAME}_slow.mp4"


# Clean up when we are done
rm -f "${NAME}.ac3" "${NAME}.wav" "${NAME}_.wav" "${NAME}" "${NAME}_track1.h264"

Skrip ini membuat salinan MP4 dengan postfix _slow.

OSi
sumber