@@ -42,6 +42,26 @@ public function isAvailable(FileInfo $file): bool {
4242		return  is_string ($ this binary );
4343	}
4444
45+ 	private  function  connectDirect (File $ filestring |false  {
46+ 		if  (stream_get_meta_data ($ filefopen ('r ' ))['seekable ' ] !== true ) {
47+ 			return  false ;
48+ 		}
49+ 
50+ 		// Checks for availability to access the video file directly via HTTP/HTTPS. 
51+ 		// Returns a string containing URL if available. Only implemented and tested 
52+ 		// with Amazon S3 currently.  In all other cases, return false. ffmpeg 
53+ 		// supports other protocols so this function may expand in the future. 
54+ 		$ gddValues$ filegetStorage ()->getDirectDownload ($ filegetName ());
55+ 
56+ 		if  (is_array ($ gddValues
57+ 			if  (array_key_exists ('url ' , $ gddValuesarray_key_exists ('presigned ' , $ gddValues
58+ 				$ directUrlstr_starts_with ($ gddValues'url ' ], 'http ' ) && ($ gddValues'presigned ' ] === true )) ? $ gddValues'url ' ] : false ;
59+ 				return  $ directUrl
60+ 			}
61+ 		}
62+ 		return  false ;
63+ 	}
64+ 
4565	/** 
4666	 * {@inheritDoc} 
4767	 */ 
@@ -51,54 +71,60 @@ public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
5171		if  (!$ this isAvailable ($ file
5272			return  null ;
5373		}
54- 
5574		$ resultnull ;
56- 		if  ($ this useTempFile ($ file
57- 			// Try downloading 5 MB first, as it's likely that the first frames are present there. 
58- 			// In some cases this doesn't work, for example when the moov atom is at the 
59- 			// end of the file, so if it fails we fall back to getting the full file. 
60- 			// Unless the file is not local (e.g. S3) as we do not want to download the whole (e.g. 37Gb) file 
61- 			if  ($ filegetStorage ()->isLocal ()) {
62- 				$ sizeAttempts5242880 , null ];
75+ 		$ connectDirect$ this connectDirect ($ file
76+ 		if  (($ connectDirectfalse ) || $ fileisEncrypted ()) {
77+ 			// If HTTP/HTTPS direct connect is not available or if the file is encrypted, 
78+ 			// process normally with temp files 
79+ 			if  ($ this useTempFile ($ file
80+ 				// Try downloading 5 MB first, as it's likely that the first frames are 
81+ 				// present there. In some cases this doesn't work (e.g. when the 
82+ 				// moov atom is at the end) so if it fails, fall back to 
83+ 				// getting the full file, unless the file is not local as we do not want 
84+ 				// to download the whole (e.g. 37GB) file from remote. 
85+ 				if  ($ filegetStorage ()->isLocal ()) {
86+ 					$ sizeAttempts5242880 , null ];
87+ 				} else  {
88+ 					$ sizeAttempts5242880 ];
89+ 				}
6390			} else  {
64- 				$ sizeAttempts5242880 ];
91+ 				// size is irrelevant, only attempt once 
92+ 				$ sizeAttemptsnull ];
6593			}
66- 		} else  {
67- 			// size is irrelevant, only attempt once 
68- 			$ sizeAttemptsnull ];
69- 		}
7094
71- 		foreach  ($ sizeAttemptsas  $ size
72- 			$ absPath$ this getLocalFile ($ file$ size
73- 			if  ($ absPathfalse ) {
74- 				Server::get (LoggerInterface::class)->error (
75- 					'Failed to get local file to generate thumbnail for:  '  . $ filegetPath (),
76- 					['app '  => 'core ' ]
77- 				);
78- 				return  null ;
79- 			}
80- 
81- 			$ result$ this generateThumbNail ($ maxX$ maxY$ absPath5 );
82- 			if  ($ resultnull ) {
83- 				$ result$ this generateThumbNail ($ maxX$ maxY$ absPath1 );
84- 				if  ($ resultnull ) {
85- 					$ result$ this generateThumbNail ($ maxX$ maxY$ absPath0 );
95+ 			foreach  ($ sizeAttemptsas  $ size
96+ 				$ absPath$ this getLocalFile ($ file$ size
97+ 				if  ($ absPathfalse ) {
98+ 					Server::get (LoggerInterface::class)->error (
99+ 						'Failed to get local file to generate thumbnail for:  ' 
100+ 						. $ filegetPath (), ['app '  => 'core ' ]
101+ 					);
102+ 					return  null ;
86103				}
87- 			}
88104
89- 			$ this cleanTmpFiles ();
105+ 				$ result$ this generateThumbNail ($ maxX$ maxY$ absPath5 ))
106+ 							?? ($ this generateThumbNail ($ maxX$ maxY$ absPath1 ))
107+ 							?? ($ this generateThumbNail ($ maxX$ maxY$ absPath0 ));
90108
91- 			if  ($ resultnull ) {
92- 				break ;
109+ 				$ this cleanTmpFiles ();
110+ 
111+ 				if  ($ resultnull ) {
112+ 					break ;
113+ 				}
93114			}
115+ 		} else  {
116+ 			// HTTP/HTTPS direct connect is available so pass the URL directly to ffmpeg 
117+ 			$ result$ this generateThumbNail ($ maxX$ maxY$ connectDirect5 ))
118+ 				?? ($ this generateThumbNail ($ maxX$ maxY$ connectDirect1 ))
119+ 				?? ($ this generateThumbNail ($ maxX$ maxY$ connectDirect0 ));
94120		}
95- 
96121		return  $ result
97122	}
98123
99124	private  function  useHdr (string  $ absPathbool  {
100125		// load ffprobe path from configuration, otherwise generate binary path using ffmpeg binary path 
101- 		$ ffprobe_binary$ this config ->getSystemValue ('preview_ffprobe_path ' , null ) ?? (pathinfo ($ this binary , PATHINFO_DIRNAME ) . '/ffprobe ' );
126+ 		$ ffprobe_binary$ this config ->getSystemValue ('preview_ffprobe_path ' , null ))
127+ 			?? (pathinfo ($ this binary , PATHINFO_DIRNAME ) . '/ffprobe ' );
102128		// run ffprobe on the video file to get value of "color_transfer" 
103129		$ test_hdr_cmd$ ffprobe_binary'-select_streams ' , 'v:0 ' ,
104130			'-show_entries ' , 'stream=color_transfer ' ,
0 commit comments