diff --git a/lib/Exif.php b/lib/Exif.php index a5879a1b..d404b467 100644 --- a/lib/Exif.php +++ b/lib/Exif.php @@ -26,6 +26,16 @@ class Exif { * @param File $file */ public static function getExifFromFile(File &$file) { + // Borrowed from previews + // https://github.com/nextcloud/server/blob/19f68b3011a3c040899fb84975a28bd746bddb4b/lib/private/Preview/ProviderV2.php + if (!$file->isEncrypted() && $file->getStorage()->isLocal()) { + $path = $file->getStorage()->getLocalFile($file->getInternalPath()); + if (is_string($path)) { + return self::getExifFromLocalPath($path); + } + } + + // Fallback to reading as a stream $handle = $file->fopen('rb'); if (!$handle) { throw new \Exception('Could not open file'); @@ -36,6 +46,28 @@ class Exif { return $exif; } + /** Get exif data as a JSON object from a local file path */ + public static function getExifFromLocalPath(string $path) { + $pipes = []; + $proc = proc_open(['exiftool', '-json', $path], [ + 1 => array('pipe', 'w'), + 2 => array('pipe', 'w'), + ], $pipes); + $stdout = stream_get_contents($pipes[1]); + + // Clean up + fclose($pipes[1]); + fclose($pipes[2]); + proc_close($proc); + + // Parse the json + $json = json_decode($stdout, true); + if (!$json) { + throw new \Exception('Could not read exif data'); + } + return $json[0]; + } + /** * Get exif data as a JSON object from a stream. * @param resource $handle @@ -43,15 +75,15 @@ class Exif { public static function getExifFromStream(&$handle) { // Start exiftool and output to json $pipes = []; - $proc = proc_open('exiftool -json -', [ + $proc = proc_open(['exiftool', '-json', '-fast', '-'], [ 0 => array('pipe', 'rb'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w'), ], $pipes); // Write the file to exiftool's stdin - // Assume exif exists in the first 256 kb of the file - stream_copy_to_stream($handle, $pipes[0], 256 * 1024); + // Warning: this is slow for big files + stream_copy_to_stream($handle, $pipes[0]); fclose($pipes[0]); // Get output from exiftool @@ -83,7 +115,7 @@ class Exif { // Check if found something if (isset($dt) && !empty($dt)) { - $dt = \DateTime::createFromFormat('Y:m:d H:i:s', $dt); + $dt = \DateTime::createFromFormat('Y:m:d H:i:s', $dt, new \DateTimeZone("UTC")); if ($dt && $dt->getTimestamp() > -5364662400) { // 1800 A.D. return $dt->getTimestamp(); }