浏览代码

Completed partial content implementation
videojs layout fixes
Added translations

Sergio Brighenti 6 年之前
父节点
当前提交
c60e3d059e

+ 2 - 1
CHANGELOG.md

@@ -1,7 +1,8 @@
 ## v2.5
 + Updated project license to <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU AGPLv3</a>.
 + Added self update feature.
-+ Working on partial content implementation (streaming seek con chromium based browsers).
++ Added partial content implementation (stream seeking on chromium based browsers).
++ Improved video.js alignment with large videos.
 
 ## v2.4.1
 + Fixed error message when the file is too large. (#15)

+ 6 - 1
README.md

@@ -159,11 +159,16 @@ location / {
 	<img src="https://i.imgur.com/2ZRd27y.png" width="400" title="Public image upload view">
 </p>
 
+## License
+This software is licensed under the <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>, available in this repository.
+As a "copyright notice" it is sufficient to keep the small footer at the bottom of the page, also to help other people to learn about this project!
+
 ## Built with
-+ Slim 3, since `v2.0` (https://www.slimframework.com/)
++ Slim 3, since `v2.0` (https://www.slimframework.com/) and some great PHP packages (Flysystem, Intervention Image, Twig, etc)
 + FlightPHP, up to `v1.x` (http://flightphp.com/)
 + Bootstrap 4 (https://getbootstrap.com/)
 + Font Awesome 5 (http://fontawesome.com)
 + ClipboardJS (https://clipboardjs.com/)
 + HighlightJS (https://highlightjs.org/)
 + JQuery (https://jquery.com/)
++ video.js (https://videojs.com/)

+ 2 - 2
app/Controllers/UpgradeController.php

@@ -101,10 +101,10 @@ class UpgradeController extends Controller
 
 			$jsonResponse['status'] = 'OK';
 			if (version_compare($json[0]->tag_name, PLATFORM_VERSION, '>')) {
-				$jsonResponse['message'] = lang('new_version_available', $json[0]->tag_name); //"New version {$json[0]->tag_name} available!";
+				$jsonResponse['message'] = lang('new_version_available', $json[0]->tag_name);
 				$jsonResponse['upgrade'] = true;
 			} else {
-				$jsonResponse['message'] = lang('already_latest_version');//'You have already the latest version.';
+				$jsonResponse['message'] = lang('already_latest_version');
 				$jsonResponse['upgrade'] = false;
 			}
 			return $response->withJson($jsonResponse, 200);

+ 33 - 36
app/Controllers/UploadController.php

@@ -107,13 +107,6 @@ class UploadController extends Controller
 				$type = explode('/', $media->mimetype)[0];
 				if ($type === 'text') {
 					$media->text = $filesystem->read($media->storage_path);
-				} else if (in_array($type, ['image', 'video'])) {
-					$url = urlFor("/$args[userCode]/$args[mediaCode]/raw");
-					$header = "<{$url}>; rel=preload; as={$type}";
-					if ($this->session->get('logged', false)) {
-						$header .= '; nopush';
-					}
-					$response = $response->withHeader('Link', $header);
 				}
 
 			} catch (FileNotFoundException $e) {
@@ -316,6 +309,7 @@ class UploadController extends Controller
 	 */
 	protected function streamMedia(Request $request, Response $response, Filesystem $storage, $media, string $disposition = 'inline'): Response
 	{
+		set_time_limit(0);
 		$mime = $storage->getMimetype($media->storage_path);
 
 		if ($request->getParam('width') !== null && explode('/', $mime)[0] === 'image') {
@@ -332,60 +326,63 @@ class UploadController extends Controller
 				->withHeader('Content-Disposition', $disposition . ';filename="scaled-' . pathinfo($media->filename)['filename'] . '.png"')
 				->write($image);
 		} else {
-
 			$stream = new Stream($storage->readStream($media->storage_path));
-			$start = 0;
-			$end = $stream->getSize();
+
+			if (!in_array(explode('/', $mime)[0], ['image', 'video', 'audio']) || $disposition === 'attachment') {
+				return $response->withHeader('Content-Type', $mime)
+					->withHeader('Content-Disposition', $disposition . '; filename="' . $media->filename . '"')
+					->withHeader('Content-Length', $stream->getSize())
+					->withBody($stream);
+			}
+
+			$end = $stream->getSize() - 1;
+
 			if ($request->getServerParam('HTTP_RANGE') !== null) {
-				list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
+				list(, $range) = explode('=', $request->getServerParam('HTTP_RANGE'), 2);
 
 				if (strpos($range, ',') !== false) {
 					return $response->withHeader('Content-Type', $mime)
 						->withHeader('Content-Disposition', $disposition . '; filename="' . $media->filename . '"')
-						->withHeader('Content-Length', $storage->getSize($media->storage_path))
+						->withHeader('Content-Length', $stream->getSize())
 						->withHeader('Accept-Ranges', 'bytes')
 						->withHeader('Content-Range', "0,{$stream->getSize()}")
 						->withStatus(416)
 						->withBody($stream);
 				}
 
-				if ($range == '-') {
-					$start = $stream->getSize() - substr($range, 1);
+				if ($range === '-') {
+					$start = $stream->getSize() - (int)substr($range, 1);
 				} else {
 					$range = explode('-', $range);
-					$start = $range[0];
-					$end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $end;
+					$start = (int)$range[0];
+					$end = (isset($range[1]) && is_numeric($range[1])) ? (int)$range[1] : $stream->getSize();
 				}
 
 				$end = ($end > $stream->getSize() - 1) ? $stream->getSize() - 1 : $end;
+				$stream->seek($start);
 
-				if ($start > $end || $start > $stream->getSize() - 1 || $end >= $stream->getSize()) {
-					return $response->withHeader('Content-Type', $mime)
-						->withHeader('Content-Disposition', $disposition . '; filename="' . $media->filename . '"')
-						->withHeader('Content-Length', $storage->getSize($media->storage_path))
-						->withHeader('Accept-Ranges', 'bytes')
-						->withHeader('Content-Range', "0,{$stream->getSize()}")
-						->withStatus(416)
-						->withBody($stream);
+				$buffer = 16384;
+				$readed = $start;
+				while ($readed < $end) {
+					if ($readed + $buffer > $end) {
+						$buffer = $end - $readed + 1;
+					}
+					echo $stream->read($buffer);
+					$readed += $buffer;
 				}
 
-				$stream->seek($start);
+				return $response->withHeader('Content-Type', $mime)
+					->withHeader('Content-Length', $end - $start + 1)
+					->withHeader('Accept-Ranges', 'bytes')
+					->withHeader('Content-Range', "bytes $start-$end/{$stream->getSize()}")
+					->withStatus(206);
 			}
 
-			$response->getBody()->write($stream->getContents());
-
 			return $response->withHeader('Content-Type', $mime)
-				->withHeader('Content-Disposition', $disposition . '; filename="' . $media->filename . '"')
 				->withHeader('Content-Length', $stream->getSize())
 				->withHeader('Accept-Ranges', 'bytes')
-				->withHeader('Content-Range', "bytes $start-$end/{$stream->getSize()}")
-				->withStatus(206);
-
-//			return $response
-//				->withHeader('Content-Type', $mime)
-//				->withHeader('Content-Disposition', $disposition . '; filename="' . $media->filename . '"')
-//				->withHeader('Content-Length', $storage->getSize($media->storage_path))
-//				->withBody(new Stream($storage->readStream($media->storage_path)));
+				->withStatus(200)
+				->withBody($stream);
 		}
 	}
 }

+ 8 - 10
resources/lang/en.lang.php

@@ -1,32 +1,25 @@
 <?php
 
 return [
-
 	'lang' => 'English',
-
 	'yes' => 'Yes',
 	'no' => 'No',
 	'send' => 'Send',
 	'no_media' => 'No media found.',
-
 	'login.username' => 'Username or E-Mail',
 	'password' => 'Password',
 	'login' => 'Login',
 	'username' => 'Username',
-
 	'home' => 'Home',
 	'users' => 'Users',
 	'system' => 'System',
 	'profile' => 'Profile',
 	'logout' => 'Logout',
-
 	'pager.next' => 'Next',
 	'pager.previous' => 'Previous',
-
 	'copy_link' => 'Copy link',
 	'public.telegram' => 'Share on Telegram',
 	'public.delete_text' => 'Are you sure you want to delete this item? It will be gone forever!',
-
 	'preview' => 'Preview',
 	'filename' => 'Filename',
 	'size' => 'Size',
@@ -38,7 +31,6 @@ return [
 	'delete' => 'Delete',
 	'publish' => 'Publish',
 	'hide' => 'Hide',
-
 	'files' => 'Files',
 	'orphaned_files' => 'Orphaned Files',
 	'theme' => 'Theme',
@@ -47,7 +39,6 @@ return [
 	'save' => 'Save',
 	'used' => 'Used',
 	'system_info' => 'System Information',
-
 	'user.create' => 'Create User',
 	'user.edit' => 'Edit User',
 	'is_active' => 'Is active',
@@ -66,7 +57,6 @@ return [
 	'open' => 'Open',
 	'confirm' => 'Confirmation',
 	'confirm_string' => 'Are you sure?',
-
 	'installed' => 'Installation completed successfully!',
 	'bad_login' => 'Wrong credentials.',
 	'account_disabled' => 'Your account is disabled.',
@@ -95,4 +85,12 @@ return [
 	'name' => 'Name',
 	'maintenance' => 'Maintenance',
 	'clean_orphaned_uploads' => 'Clean Orphaned Uploads',
+	'path_not_writable' => 'The output path is not writable.',
+	'already_latest_version' => 'You already have the latest version.',
+	'new_version_available' => 'New version %s available!',
+	'cannot_retrieve_file' => 'Cannot retrieve the file.',
+	'file_size_no_match' => 'The downloaded file doesn\'t match the correct file size.',
+	'check_for_updates' => 'Check for updates',
+	'upgrade' => 'Upgrade',
+	'updates' => 'Updates',
 ];

+ 8 - 10
resources/lang/it.lang.php

@@ -1,32 +1,25 @@
 <?php
 
 return [
-
 	'lang' => 'Italiano',
-
 	'yes' => 'Sì',
 	'no' => 'No',
 	'send' => 'Invia',
 	'no_media' => 'Nessun media trovato.',
-
 	'login.username' => 'Username o E-Mail',
 	'password' => 'Password',
 	'login' => 'Accedi',
 	'username' => 'Username',
-
 	'home' => 'Home',
 	'users' => 'Utenti',
 	'system' => 'Sistema',
 	'profile' => 'Profilo',
 	'logout' => 'Esci',
-
 	'pager.next' => 'Avanti',
 	'pager.previous' => 'Indietro',
-
 	'copy_link' => 'Copia link',
 	'public.telegram' => 'Condividi su Telegram',
 	'public.delete_text' => 'Sei sicuro di voler eliminare questo elemento? Andrà perso per sempre!',
-
 	'preview' => 'Anteprima',
 	'filename' => 'Nome file',
 	'size' => 'Dimensione',
@@ -38,7 +31,6 @@ return [
 	'delete' => 'Elimina',
 	'publish' => 'Pubblica',
 	'hide' => 'Nascondi',
-
 	'files' => 'File',
 	'orphaned_files' => 'File orfani',
 	'theme' => 'Tema',
@@ -47,7 +39,6 @@ return [
 	'save' => 'Salva',
 	'used' => 'Usato',
 	'system_info' => 'Informazioni di Sistema',
-
 	'user.create' => 'Crea Utente',
 	'user.edit' => 'Modifica Utente',
 	'is_active' => 'Attivo',
@@ -66,7 +57,6 @@ return [
 	'open' => 'Apri',
 	'confirm' => 'Conferma',
 	'confirm_string' => 'Sei sicuro?',
-
 	'installed' => 'Installazione completata!',
 	'bad_login' => 'Credenziali errate.',
 	'account_disabled' => 'Il tuo account è disattivato.',
@@ -95,4 +85,12 @@ return [
 	'name' => 'Nome',
 	'maintenance' => 'Manutenzione',
 	'clean_orphaned_uploads' => 'Pulisci upload orfani',
+	'path_not_writable' => 'Il percorso di output non è scrivibile.',
+	'already_latest_version' => 'Hai già l\'ultima versione disponibile.',
+	'new_version_available' => 'Nuova versione disponibile: %s',
+	'cannot_retrieve_file' => 'Impossibile scaricare il file.',
+	'file_size_no_match' => 'La dimensione del file scaricato non è corretta.',
+	'check_for_updates' => 'Controllo aggiornamenti',
+	'upgrade' => 'Upgrade',
+	'updates' => 'Aggiornamenti',
 ];

+ 1 - 1
resources/templates/dashboard/system.twig

@@ -86,7 +86,7 @@
 
                             <div class="col">
                                 <form method="post" action="{{ route('system.upgrade') }}">
-                                    <button type="submit" id="doUpgradeButton" class="btn btn-block btn-outline-success"><i class="fas fa-cloud-download-alt fa-fw"></i> {{ lang('update_now') }}</button>
+                                    <button type="submit" id="doUpgradeButton" class="btn btn-block btn-outline-success" disabled><i class="fas fa-cloud-download-alt fa-fw"></i> {{ lang('upgrade') }}</button>
                                 </form>
                             </div>
                         </div>

+ 2 - 2
resources/templates/upload/public.twig

@@ -61,14 +61,14 @@
                     </div>
                 {% elseif media.mimetype starts with 'video' %}
                     <div class="media-player">
-                        <video id="player" class="video-js vjs-fluid vjs-big-play-centered" autoplay controls loop preload="auto" data-setup='{"responsive": true }'>
+                        <video id="player" class="video-js vjs-big-play-centered vjs-16-9" autoplay controls loop preload="auto" data-setup='{"responsive": true }'>
                             <source src="{{ urlFor('/' ~ media.user_code ~ '/' ~ media.code ~ '.' ~ extension ~ '/raw') }}" type="{{ media.mimetype }}">
                             Your browser does not support HTML5 video.
                         </video>
                     </div>
                 {% elseif media.mimetype starts with 'audio' %}
                     <div class="media-player">
-                        <audio id="player"  class="video-js vjs-fluid vjs-big-play-centered" autoplay controls loop preload="auto" data-setup='{"responsive": true }'>
+                        <audio id="player"  class="video-js vjs-big-play-centered vjs-16-9" autoplay controls loop preload="auto" data-setup='{"responsive": true }'>
                             <source src="{{ urlFor('/' ~ media.user_code ~ '/' ~ media.code ~ '.' ~ extension ~ '/raw') }}" type="{{ media.mimetype }}">
                             Your browser does not support HTML5 audio.
                         </audio>