Baru -baru ini, penangkap bingkai FFMPEGFRAMEGRABBER menggunakan paket FFMPEG JAVACV telah menyinkronkan bingkai audio yang ditangkap dan bingkai video. Metode sinkronisasi yang digunakan adalah menyinkronkan video ke audio.
Program dan Kode Sumber
Gagasan spesifiknya adalah sebagai berikut:
(1) Pertama -tama perkenalkan bagaimana FFMPEG menangkap gambar dan suara file video
FFMPEGFRAMEGRABBER FG = baru FFMPEGFRAMEGRABBER ("jalur file video atau URL); Setelah mendapatkan objek Capture Frame, memanggil metode ambil () akan mengembalikan objek bingkai yang ditangkap. Bingkai ini dapat berupa bingkai video atau bingkai audio, karena frame audio dan video diatur terlebih dahulu pada waktu pemutaran sesuai dengan cap waktu. Tentu saja, bingkai yang ditangkap semuanya didekodekan dan disimpan di objek java.nio.buffer. Untuk bingkai video, buffernya adalah menyimpan data piksel gambar, seperti RGB, dan kemudian lulus
BufferedImage Bi = (Java2DFrameConverter ()) baru). GetBufferedImage (F);
Anda bisa mendapatkan gambar, dan gambar yang diperoleh dapat diproses dalam serangkaian proses atau ditampilkan langsung pada komponen ayunan tanpa diproses. Sesuai dengan bingkai audio, buffer adalah data PCM yang menyimpan audio. PCM ini dapat mengapung atau pendek, dan kemudian metode Sourcedataline.write di java.sounds.sample dapat digunakan untuk menulis data PCM audio ini ke speaker.
(2) Kemudian perkenalkan cara terus memainkan bingkai yang diperoleh. Pertama, mainkan videonya secara terpisah:
while (true) {frame f = fg.grab (); if (f.image! = null) label.seticon (gambar baru ((java2dframeConverter ()). GetBufferedImage (f))); Thread.sleep (1000/video frame rate); } Hal yang sama berlaku untuk bermain audio secara terpisah, cukup tulis data ke kartu suara. contoh
(3) Model produksi dan konsumen.
Gambar di atas adalah metode yang diimplementasikan oleh program. Bingkai yang ditangkap dinilai menggunakan mode produser. Jika itu adalah bingkai video, itu akan diproduksi ke dalam video FIFO. Jika itu adalah bingkai audio, itu akan diproduksi ke Audio FIFO. Kemudian utas pemutaran audio dan utas pemutaran video mengkonsumsi bingkai dari gudang bingkai masing -masing. Mode konsumen produksi diadopsi karena kecepatan penangkapan bingkai lebih besar dari konsumsi bingkai, jadi kami lebih suka menangkap bingkai untuk buffering, atau preprocess lebih lanjut frame yang ditangkap, sedangkan utas pemutaran video dan audio hanya perlu secara langsung bermain dan menampilkan bingkai yang diproses.
(4) Metode untuk mewujudkan sinkronisasi audio dan video: Mainkan semua bingkai video dalam dua frame audio.
Untuk mencapai sinkronisasi audio dan video, Anda harus memiliki perangko waktu bingkai. Bingkai yang ditangkap di sini hanya pemutaran waktu pemutar, dan tidak ada DT waktu yang diterjemahkan, jadi kita hanya perlu memutuskan cap waktu pemutaran berdasarkan cap waktu pemutaran.
Implementasi program didasarkan pada gambar di atas. Ketika utas audio mulai memutar bingkai audio A1, metode setRun dari utas video dipanggil, dan kursus cap waktu bingkai audio dan perangko bingkai audio bingkai berikutnya diteruskan ke utas video dalam keadaan tunggu. Kemudian utas video dimulai dan mulai mengeluarkan bingkai video G1 dari video FIFO, dan kemudian menghitung perbedaan waktu antara G1 dan A1 sebagai penundaan pemutaran. After Thread.sleep (T1), utas video menampilkan gambar pada komponen ayunan, seperti jlabel.seticon (gambar). Kemudian utas video mengeluarkan bingkai gambar G2 lain dan membandingkan cap waktu G2 dengan cap waktu A2. Jika cap waktu G2 kurang dari A2, utas video terus menunda T2 dan memainkan gambar G2. Maka G3 sama dengan yang seharusnya, sampai G4 diperoleh dan A2 dibandingkan dengan A2 dan menemukan bahwa cap waktu G4 lebih besar dari A2, kemudian utas video memasuki status tunggu dan menunggu startup berikutnya. Kemudian setelah utas audio memainkan bingkai audio A1, ia mengeluarkan bingkai audio A3 dari gudang, kemudian melewati cap waktu A2 dan cap waktu A3 ke utas video, dan kemudian mulai memutar A2, dan kemudian utas video yang diblokir terus diputar.
(5) Sesuaikan waktu tunda secara dinamis
Karena PC pribadi bukan sistem operasi real-time, yaitu Thread.sleep tidak akurat dan dibatasi oleh kartu suara untuk bermain suara, ide implementasi dasar di atas perlu ditingkatkan. Pertama -tama, metode Java Sourcedataline adalah untuk mengekstrak data yang ditulis oleh utas audio dari buffer internal dengan kecepatan tertentu. Jika data yang ditulis oleh audio dikeluarkan, pemutaran audio akan tergagap. Namun, jika terlalu banyak data audio ditulis pada satu waktu, audio dan video mungkin keluar dari sinkronisasi. Oleh karena itu, perlu untuk memastikan bahwa buffer internal dari Sourcedataline memiliki data tertentu, jika tidak maka akan menyebabkan lag, tetapi jumlah data tidak terlalu banyak. Karena itu, kami menyesuaikan pemutaran suara dari G3 ke A2. Karena ketidakakuratan keterlambatan, data yang ditulis dalam bingkai A1 dapat dihapus oleh kartu suara sebelum waktu telah mencapai T6. Oleh karena itu, setelah memainkan gambar G3, utas suara akan menilai untuk menilai berdasarkan jumlah data yang dikembalikan oleh Sourcedataline.Available (). Jika jumlah data akan selesai, waktu tunda T4 dari G3 ke A2 dikurangi. Ini memastikan bahwa volume data tidak akan berubah menjadi 0 dan menyebabkan kegagapan suara.
(6) Berikut ini adalah diagram hasil dari tes program di bawah Windows 64 dan Ubuntu14: pemutarannya relatif halus, dan sinkronisasi juga dimungkinkan, tetapi jika pemutaran dihidupkan, itu akan macet jika penguin menulis kode di IDE seperti IDEA. Bagaimanapun, ide juga dikembangkan di Java, sehingga pengoperasian ide akan memengaruhi program Java lainnya, tetapi proses lain tidak.
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.