@@ -4,6 +4,45 @@ use crate::message::Message;
44
55#[ allow( dead_code) ]
66pub fn generate_thumbnail ( path : & PathBuf ) -> Vec < u8 > {
7+ let is_video = if let Some ( ext) = path. extension ( ) . and_then ( |e| e. to_str ( ) ) {
8+ let ext_lower = ext. to_lowercase ( ) ;
9+ ext_lower == "mp4" || ext_lower == "mkv" || ext_lower == "avi" || ext_lower == "mov" || ext_lower == "webm" || ext_lower == "wmv" || ext_lower == "flv"
10+ } else {
11+ false
12+ } ;
13+
14+ if is_video {
15+ if let Ok ( mut player) = media_sort_backend:: media:: mpv_context:: MpvContext :: new ( ) {
16+ if player. load_file ( path) . is_ok ( ) {
17+ player. set_paused ( true ) ;
18+ let start_time = std:: time:: Instant :: now ( ) ;
19+ let mut loaded = false ;
20+ while start_time. elapsed ( ) < std:: time:: Duration :: from_millis ( 500 ) {
21+ let ( w, h) = player. get_video_size ( ) ;
22+ if w > 0 && h > 0 {
23+ loaded = true ;
24+ break ;
25+ }
26+ std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 10 ) ) ;
27+ }
28+
29+ if loaded {
30+ let render_w = 128 ;
31+ let render_h = 128 ;
32+ let mut buffer = vec ! [ 0u8 ; render_w * render_h * 4 ] ;
33+ if player. render_frame ( render_w as i32 , render_h as i32 , & mut buffer) . is_ok ( ) {
34+ if let Some ( rgba) = image:: RgbaImage :: from_raw ( render_w as u32 , render_h as u32 , buffer) {
35+ let mut buf = std:: io:: Cursor :: new ( Vec :: new ( ) ) ;
36+ if rgba. write_to ( & mut buf, image:: ImageFormat :: Png ) . is_ok ( ) {
37+ return buf. into_inner ( ) ;
38+ }
39+ }
40+ }
41+ }
42+ }
43+ }
44+ }
45+
746 if let Ok ( img) = image:: open ( path) {
847 let thumbnail = img. thumbnail ( 128 , 128 ) ;
948 let mut buf = std:: io:: Cursor :: new ( Vec :: new ( ) ) ;
0 commit comments