Added Tagging, Update to Laravel 5.5, Enabled Video
This commit is contained in:
parent
3012004901
commit
96fadc5080
@ -67,6 +67,11 @@ class PhotoImport extends Command
|
||||
{
|
||||
$tags = explode(',',$this->option('tags'));
|
||||
$t = Tag::whereIn('tag',$tags)->pluck('id')->toArray();
|
||||
if (! $t OR count($t) != count($tags))
|
||||
{
|
||||
$this->error(sprintf('Tag [%s] dont exist',join('|',$tags)));
|
||||
abort(501);
|
||||
}
|
||||
}
|
||||
|
||||
// People
|
||||
@ -74,6 +79,11 @@ class PhotoImport extends Command
|
||||
{
|
||||
$tags = explode(',',$this->option('people'));
|
||||
$p = Person::whereIn('tag',$tags)->pluck('id')->toArray();
|
||||
if (! $p OR count($p) != count($tags))
|
||||
{
|
||||
$this->error(sprintf('People [%s] dont exist',join('|',$tags)));
|
||||
abort(501);
|
||||
}
|
||||
}
|
||||
|
||||
$c = 0;
|
||||
|
128
app/Helpers/VideoStream.php
Normal file
128
app/Helpers/VideoStream.php
Normal file
@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace App\Helpers;
|
||||
|
||||
/**
|
||||
* Description of VideoStream
|
||||
*
|
||||
* @author Rana
|
||||
* @link http://codesamplez.com/programming/php-html5-video-streaming-tutorial
|
||||
**/
|
||||
class VideoStream
|
||||
{
|
||||
private $path = '';
|
||||
private $stream = '';
|
||||
private $buffer = 102400;
|
||||
private $start = -1;
|
||||
private $end = -1;
|
||||
private $size = 0;
|
||||
|
||||
function __construct($filePath)
|
||||
{
|
||||
$this->path = $filePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open stream
|
||||
**/
|
||||
private function open()
|
||||
{
|
||||
if (! ($this->stream = fopen($this->path,'rb')) ) {
|
||||
die('Could not open stream for reading');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set proper header to serve the video content
|
||||
**/
|
||||
private function setHeader()
|
||||
{
|
||||
ob_get_clean();
|
||||
header('Content-Type: video/mp4');
|
||||
header('Cache-Control: max-age=2592000, public');
|
||||
header('Expires: '.gmdate('D, d M Y H:i:s',time()+2592000) . ' GMT');
|
||||
header('Last-Modified: '.gmdate('D, d M Y H:i:s',@filemtime($this->path)) . ' GMT' );
|
||||
$this->start = 0;
|
||||
$this->size = filesize($this->path);
|
||||
$this->end = $this->size - 1;
|
||||
header('Accept-Ranges: 0-'.$this->end);
|
||||
|
||||
if (isset($_SERVER['HTTP_RANGE'])) {
|
||||
|
||||
$c_start = $this->start;
|
||||
$c_end = $this->end;
|
||||
|
||||
list(,$range) = explode('=',$_SERVER['HTTP_RANGE'],2);
|
||||
if (strpos($range,',') !== false) {
|
||||
header('HTTP/1.1 416 Requested Range Not Satisfiable');
|
||||
header("Content-Range: bytes $this->start-$this->end/$this->size");
|
||||
exit;
|
||||
}
|
||||
if ($range == '-') {
|
||||
$c_start = $this->size - substr($range,1);
|
||||
}else{
|
||||
$range = explode('-',$range);
|
||||
$c_start = $range[0];
|
||||
|
||||
$c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $c_end;
|
||||
}
|
||||
$c_end = ($c_end > $this->end) ? $this->end : $c_end;
|
||||
if ($c_start > $c_end || $c_start > $this->size - 1 || $c_end >= $this->size) {
|
||||
header('HTTP/1.1 416 Requested Range Not Satisfiable');
|
||||
header("Content-Range: bytes $this->start-$this->end/$this->size");
|
||||
exit;
|
||||
}
|
||||
$this->start = $c_start;
|
||||
$this->end = $c_end;
|
||||
$length = $this->end - $this->start + 1;
|
||||
fseek($this->stream,$this->start);
|
||||
header('HTTP/1.1 206 Partial Content');
|
||||
header("Content-Length: ".$length);
|
||||
header("Content-Range: bytes $this->start-$this->end/".$this->size);
|
||||
}
|
||||
else
|
||||
{
|
||||
header("Content-Length: ".$this->size);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* close curretly opened stream
|
||||
**/
|
||||
private function end()
|
||||
{
|
||||
fclose($this->stream);
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* perform the streaming of calculated range
|
||||
**/
|
||||
private function stream()
|
||||
{
|
||||
$i = $this->start;
|
||||
set_time_limit(0);
|
||||
while(!feof($this->stream) && $i <= $this->end) {
|
||||
$bytesToRead = $this->buffer;
|
||||
if (($i+$bytesToRead) > $this->end) {
|
||||
$bytesToRead = $this->end - $i + 1;
|
||||
}
|
||||
$data = fread($this->stream,$bytesToRead);
|
||||
echo $data;
|
||||
flush();
|
||||
$i += $bytesToRead;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start streaming video content
|
||||
**/
|
||||
function start()
|
||||
{
|
||||
$this->open();
|
||||
$this->setHeader();
|
||||
$this->stream();
|
||||
$this->end();
|
||||
}
|
||||
}
|
@ -6,9 +6,8 @@ use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesResources;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, AuthorizesResources, DispatchesJobs, ValidatesRequests;
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
}
|
||||
|
@ -77,6 +77,7 @@ class PhotoController extends Controller
|
||||
|
||||
return redirect()->action('PhotoController@duplicates','?page='.$request->input('page'));
|
||||
}
|
||||
|
||||
public function info($id)
|
||||
{
|
||||
return view('photo.view', ['photo'=> Photo::findOrFail($id)]);
|
||||
|
@ -8,6 +8,7 @@ use Illuminate\Http\Request;
|
||||
use App\Http\Requests;
|
||||
use App\Model\Video;
|
||||
use App\Jobs\VideoDelete;
|
||||
use App\Helpers\VideoStream;
|
||||
|
||||
class VideoController extends Controller
|
||||
{
|
||||
@ -34,13 +35,11 @@ class VideoController extends Controller
|
||||
return redirect()->action('VideoController@info',[$id]);
|
||||
}
|
||||
|
||||
//@todo
|
||||
public function deletes()
|
||||
{
|
||||
return view('video.deletereview',['videos'=>Video::where('remove',1)->paginate(2)]);
|
||||
}
|
||||
|
||||
//@todo
|
||||
public function deletesUpdate(Request $request)
|
||||
{
|
||||
foreach ($request->input('video') as $id)
|
||||
@ -54,13 +53,11 @@ class VideoController extends Controller
|
||||
return redirect()->action('VideoController@deletes',$request->input('pagenext') ? '?page='.$request->input('pagenext') : NULL);
|
||||
}
|
||||
|
||||
//@todo
|
||||
public function duplicates($id=NULL)
|
||||
{
|
||||
return view('video.duplicates',['videos'=>is_null($id) ? Video::notRemove()->where('duplicate',1)->paginate(1) : Video::where('id',$id)->paginate(1)]);
|
||||
}
|
||||
|
||||
//@todo
|
||||
public function duplicatesUpdate(Request $request)
|
||||
{
|
||||
foreach ($request->input('video') as $id)
|
||||
@ -99,9 +96,8 @@ class VideoController extends Controller
|
||||
return redirect()->action('VideoController@info',[$id]);
|
||||
}
|
||||
|
||||
//@todo
|
||||
public function view($id)
|
||||
{
|
||||
return response(Video::findOrFail($id)->image())->header('Content-Type','video/mov');
|
||||
(new VideoStream(Video::findOrFail($id)->file_path()))->start();
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ Route::get('/p/info/{id}', 'PhotoController@info')->where('id', '[0-9]+');;
|
||||
Route::get('/v/info/{id}', 'VideoController@info')->where('id', '[0-9]+');;
|
||||
Route::get('/p/thumbnail/{id}', 'PhotoController@thumbnail')->where('id', '[0-9]+');;
|
||||
Route::get('/p/view/{id}', 'PhotoController@view')->where('id', '[0-9]+');;
|
||||
Route::get('/v/view/{id}', 'VideoController@view')->where('id', '[0-9]+');;
|
||||
Route::post('/p/delete/{id}', 'PhotoController@delete')->where('id', '[0-9]+');;
|
||||
Route::post('/v/delete/{id}', 'VideoController@delete')->where('id', '[0-9]+');;
|
||||
Route::post('/p/duplicates', 'PhotoController@duplicatesUpdate');
|
||||
|
@ -308,6 +308,11 @@ class Video extends Model
|
||||
return strtolower($mime ? File::mime_by_ext(pathinfo($this->filename,PATHINFO_EXTENSION)) : pathinfo($this->filename,PATHINFO_EXTENSION));
|
||||
}
|
||||
|
||||
public function view()
|
||||
{
|
||||
return sprintf('<video width="320" height="240" src="%s" controls></video>',url('/v/view/'.$this->id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Find duplicate images based on some attributes of the current image
|
||||
*/
|
||||
|
@ -21,9 +21,9 @@ class EventServiceProvider extends ServiceProvider
|
||||
* @param \Illuminate\Contracts\Events\Dispatcher $events
|
||||
* @return void
|
||||
*/
|
||||
public function boot(DispatcherContract $events)
|
||||
public function boot()
|
||||
{
|
||||
parent::boot($events);
|
||||
parent::boot();
|
||||
|
||||
//
|
||||
}
|
||||
|
@ -22,11 +22,11 @@ class RouteServiceProvider extends ServiceProvider
|
||||
* @param \Illuminate\Routing\Router $router
|
||||
* @return void
|
||||
*/
|
||||
public function boot(Router $router)
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
|
||||
parent::boot($router);
|
||||
parent::boot();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,17 +6,10 @@
|
||||
"type": "project",
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"laravel/framework": "5.2.*",
|
||||
"laravel/framework": "5.5.*",
|
||||
"james-heinrich/getid3": "^1.9"
|
||||
},
|
||||
"require-dev": {
|
||||
"fzaninotto/faker": "~1.4",
|
||||
"mockery/mockery": "0.9.*",
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"symfony/css-selector": "2.8.*|3.0.*",
|
||||
"symfony/dom-crawler": "2.8.*|3.0.*",
|
||||
"xethron/migrations-generator": "dev-l5",
|
||||
"way/generators": "dev-feature/laravel-five-stable"
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
@ -49,11 +42,5 @@
|
||||
},
|
||||
"config": {
|
||||
"preferred-install": "dist"
|
||||
},
|
||||
"repositories": {
|
||||
"repo-name": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:jamisonvalenta/Laravel-4-Generators.git"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
4842
composer.lock
generated
4842
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -157,9 +157,6 @@ return [
|
||||
App\Providers\AuthServiceProvider::class,
|
||||
App\Providers\EventServiceProvider::class,
|
||||
App\Providers\RouteServiceProvider::class,
|
||||
|
||||
Way\Generators\GeneratorsServiceProvider::class,
|
||||
Xethron\MigrationsGenerator\MigrationsGeneratorServiceProvider::class,
|
||||
],
|
||||
|
||||
/*
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'dir'=>'/var/www/sites/co.dlcm.p/store/photos',
|
||||
'dir'=>'/photos',
|
||||
'import'=>[
|
||||
'accepted'=>['jpg'],
|
||||
'accepted'=>['jpg','jpeg'],
|
||||
],
|
||||
];
|
||||
|
@ -1,9 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'dir'=>'/var/www/sites/co.dlcm.p/store/video',
|
||||
'dir'=>'/videos',
|
||||
'import'=>[
|
||||
'accepted'=>['m4v','mov','mp4','avi'],
|
||||
'log'=>'/tmp/import.log',
|
||||
],
|
||||
];
|
||||
|
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
class CreatePersonVideoTable extends Migration {
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('person_video', function(Blueprint $table)
|
||||
{
|
||||
$table->bigInteger('id', true);
|
||||
$table->timestamps();
|
||||
$table->integer('person_id');
|
||||
$table->bigInteger('video_id')->index('fk_pp_ph_idx');
|
||||
$table->unique(['person_id','video_id'], 'UNIQUE');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('person_video');
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
class CreateTagVideoTable extends Migration {
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('tag_video', function(Blueprint $table)
|
||||
{
|
||||
$table->bigInteger('id', true);
|
||||
$table->timestamps();
|
||||
$table->bigInteger('video_id');
|
||||
$table->bigInteger('tag_id')->index('pt_t_idx');
|
||||
$table->unique(['video_id','tag_id'], 'UNIQUE');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('tag_video');
|
||||
}
|
||||
|
||||
}
|
@ -3,7 +3,9 @@
|
||||
@section('content')
|
||||
<?php $data = [
|
||||
'ID'=>'id',
|
||||
'Video'=>'video',
|
||||
'Signature'=>'signature',
|
||||
'Length'=>'length',
|
||||
'Date Created'=>'datecreated',
|
||||
'File Created'=>'created',
|
||||
'File Modified'=>'modified',
|
||||
@ -53,6 +55,8 @@ function changed($k,$v,$l=0)
|
||||
$o = (new \App\Model\Video())->where('id',$id)->first();
|
||||
switch ($v) :
|
||||
case 'id': $x=$id; $y=sprintf('<a href="%s">%s</a>',url('/v/info/'.$o->id),$o->id); break;
|
||||
case 'video': $x=$o->signature(TRUE);$y=$o->view();; break;
|
||||
case 'length': $x=$y=$o->length; break;
|
||||
case 'signature': $x=$y=$o->signature(TRUE); break;
|
||||
case 'datecreated': $x=$y=$o->date_taken(); break;
|
||||
case 'created': $x=$y=$o->file_date('c',TRUE); break;
|
||||
|
@ -10,9 +10,9 @@
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<div class="col-md-2">
|
||||
<!--<a href="{{ url('/v/view/'.$video->id) }}"><img src="{{ url('/v/thumbnail/'.$video->id) }}" width="200px"></a>-->
|
||||
<div class="col-md-4">
|
||||
<div class="text-center">
|
||||
{!! $video->view() !!}
|
||||
<ul class="pagination">
|
||||
<li <?php if (! $x = $video->previous()) : ?>class="disabled"<?php endif ?>><a href="{{ $x ? url('/v/info/'.$x->id) : '#' }}"><<</a></li>
|
||||
<li <?php if (! $x = $video->next()) : ?>class="disabled"<?php endif ?>><a href="{{ $x ? url('/v/info/'.$x->id) : '#' }}">>></a></li>
|
||||
@ -20,7 +20,7 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-md-10">
|
||||
<div class="col-md-8">
|
||||
<div class="dl-horizontal">
|
||||
<dt>Signature</dt><dd>{{ $video->signature(TRUE) }}</dd>
|
||||
<dt>Filename</dt><dd>{{ $video->file_path(TRUE) }}<dd>
|
||||
|
Loading…
Reference in New Issue
Block a user