2016-02-27 22 views
8

Dựa trên bài viết này có vẻ như nó có thể sử dụng FFMPEG để phát hiện sự thay đổi cảnh trong video: http://www.luckydinosaur.com/u/ffmpeg-scene-change-detectorSử dụng FFMPEG: Cách thực hiện Phát hiện thay đổi cảnh? với mã thời gian?

Bây giờ tôi có một video sẽ hiển thị một văn bản cuốn sách và khi văn bản (word hoặc câu) được nói nó được đánh dấu. Điều gì đó giống như cuốn sách âm thanh này: https://youtu.be/lA7L6ZNVKjc

Tôi cần biết dấu thời gian khi văn bản được đánh dấu (do đó thay đổi cảnh), điều này sẽ cho phép tôi thêm thẻ dấu thời gian trên video youtube của mình, để người nghe dễ dàng điều hướng hơn thông qua audiobook.

Dòng lệnh ma thuật sẽ thực hiện điều này là gì?

Cảm ơn bạn rất nhiều!

Trả lời

8

Kết hợp bộ lọc scene (để phát hiện những thay đổi cảnh) và bộ lọc showinfo nên đạt được những gì bạn muốn:

ffmpeg -i input.flv -filter:v "select='gt(scene,0.4)',showinfo" -f null - 2> ffout 
chiết xuất

Lệnh này tất cả các khung khác với khung trước hơn (gt) 0.4 (trên thang điểm từ 0 đến 1). Đối với các khung này, thông tin được in ra (showinfo) như thế này

[Parsed_showinfo_1 @ 0x2d85e60] n: 0 pts:2537204 pts_time:2.5372 pos: 2998114 fmt:rgb24 sar:1/1 s:1920x1200 i:P iskey:1 type:I checksum:5616582E plane_checksum:[5616582E] 

Bây giờ bạn chỉ cần trích dấu thời gian. Tôi nghĩ bạn quan tâm đến pts_time. Bạn có thể làm điều đó như thế này:

grep showinfo ffout | grep pts_time:[0-9.]* -o | grep [0-9.]* -o > timestamps 

này sẽ cung cấp cho bạn danh sách tất cả timestamps:

2.5372 
4.37799 
6.65301 
8.09344 

Đối với phương pháp này để làm việc, bạn phải có một phiên bản của FFmpeg mà thực hiện việc dò tìm cảnh. Ngoài ra, bạn phải chọn một giá trị phù hợp cho ngưỡng (0.4 trong lệnh đầu tiên). Bạn có thể cố gắng tìm một ngưỡng tối ưu bằng cách chiết xuất khung cho ngưỡng khác nhau (và sau đó kiểm tra các khung bằng tay) như thế này

ffmpeg -i input.flv -filter:v "select='gt(scene,0.1)',showinfo" -vsync 0 frames/%05d.jpg 

Chỉ cần làm rõ: grep [0-9.]* không loại trừ số nguyên như tuyên bố trong câu trả lời khác. Nó khớp với bất kỳ chuỗi ký tự nào bao gồm các chữ số và dấu chấm nhưng nó cũng sẽ khớp với các số không giống như '4.4.4'. Tuy nhiên, ffmpeg không nên xuất ra dấu thời gian hình thành không đúng như vậy.

+0

grep cuối cùng trên nên được 'grep sau '[0-9] * \. [0-9] *' -o' để các grep thức là 'grep showinfo ffout | grep pts_time: [0-9.] * -o | grep '[0-9] * \. [0-9] *' -o> dấu thời gian ' '.' cần được thoát, nếu không nó sẽ khớp với bất kỳ ký tự nào – keypulsations

+1

@keypulsations,' [.] 'không khớp bất kỳ ký tự '.' nào. '[.]' là một biểu thức khung, khớp với bất kỳ ký tự đơn nào giữa các dấu ngoặc đơn.Xem thêm [hướng dẫn grep về "Lớp nhân vật và Biểu thức khung"] (https://www.gnu.org/software/grep/manual/html_node/Character-Classes-and-Bracket-Expressions.html#Character-Classes- và-Khung-Biểu thức). Trong khi 'grep [0-9.] *' Cũng sẽ khớp nhiều hơn float và số nguyên (nhưng trong thực tế không có trong đường dẫn này), regexp của bạn có thể loại trừ các số nguyên như được chỉ ra trong câu trả lời khác. – ckoehn

4

Tôi không có đại diện để đăng nhận xét về câu trả lời ở trên nhưng tôi muốn chỉ ra rằng grep được đăng bởi cả @ckoehn và @keypulsations sẽ chỉ lấy dấu thời gian là dấu phẩy động. Để lấy cả hai điểm và nguyên nổi timestamps sử dụng regex

grep showinfo ffout | grep pts_time:[0-9.]* -o | grep -E '[0-9]+(?:\.[0-9]*)?' -o > timestamps 
Các vấn đề liên quan