Skip to content

Commit

Permalink
Merge pull request #9 from jobtech-dev/develop
Browse files Browse the repository at this point in the history
First release
  • Loading branch information
ilgala committed Sep 1, 2020
2 parents 5287839 + 434e9db commit a019f69
Show file tree
Hide file tree
Showing 17 changed files with 258 additions and 44 deletions.
23 changes: 15 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ Once the last chunk has been uploaded, a `Jobtech\LaravelChunky\Jobs\MergeChunks

'mime_types' => [
'video/*' => \Jobtech\LaravelChunky\Strategies\VideoStrategy::class,
'audio/*' => \Jobtech\LaravelChunky\Strategies\AudioStrategy::class,
],

'connection' => env('CHUNKY_MERGE_CONNECTION', 'default'),
Expand Down Expand Up @@ -405,7 +406,7 @@ namespace App\MergeStrategies;
use Jobtech\LaravelChunky\Strategies\MergeStrategy;
use Jobtech\LaravelChunky\Strategies\Concerns\ChecksIntegrity;

class AudioStrategy extends MergeStrategy
class PDFStrategy extends MergeStrategy
{
use ChecksIntegrity;

Expand All @@ -414,7 +415,7 @@ class AudioStrategy extends MergeStrategy
*/
public function merge()
{
// Implement here your logic to merge audio chunks
// Implement here your logic to merge pdf chunks
}
}
```
Expand All @@ -432,8 +433,9 @@ Once completed, add your strategy into the configuration file, so you can automa

'mime_types' => [
'video/*' => \Jobtech\LaravelChunky\Strategies\VideoStrategy::class,
'audio/*' => \Jobtech\LaravelChunky\Strategies\AudioStrategy::class,
// Add here
'audio/*' => \App\MergeStrategies\AudioStrategy::class,
'application/pdf' => \App\MergeStrategies\PDFStrategy::class,
],
],

Expand All @@ -443,25 +445,30 @@ Once completed, add your strategy into the configuration file, so you can automa

## Testing

You can run the tests with:
You can run the tests with PHP unit:

```sh
$ vendor/bin/phpunit
```

or with the composer script
If you want to set custom environment variable, you can add a `.env` file for custom disks, queue or whatever you need. Tests anyway set a temporary local disk by default.

```sh
$ composer test
```
CHUNKY_CHUNK_DISK=s3
CHUNKY_MERGE_DISK=public
CHUNKY_AUTO_MERGE=false
CHUNKY_MERGE_CONNECTION=redis
CHUNKY_MERGE_QUEUE=my-custom-queue
```

## Roadmap

See the [open issues](https://github.com/jobtech-dev/laravel-chunky/issues) for a list of proposed features (and known issues).

We're working on:

* Implement more merge strategies
* Implement more merge strategies for specific mime types
* Video and audio should have dedicated strategy for each codec.
* Integrate frontend chunk upload (Not sure if necessary... there are so many packages that does it)
* Better tests
* Laravel 5.5+ compatibility
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
}
],
"require": {
"php": "^7.2",
"php": "^7.3",
"ext-fileinfo": "*",
"ext-json": "*",
"illuminate/contracts": "~5.8.0|^6.0|^7.0",
Expand Down
33 changes: 33 additions & 0 deletions scrutinizer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
filter:
excluded_paths: [tests/*]
checks:
php:
code_rating: true
remove_extra_empty_lines: true
remove_php_closing_tag: true
remove_trailing_whitespace: true
fix_use_statements:
remove_unused: true
preserve_multiple: false
preserve_blanklines: true
order_alphabetically: true
fix_php_opening_tag: true
fix_linefeed: true
fix_line_ending: true
fix_identation_4spaces: true
fix_doc_comments: true
tools:
external_code_coverage: false
php_analyzer: true
php_code_coverage: false
php_code_sniffer:
config:
standard: PSR2
filter:
paths: ['src']
php_loc:
enabled: true
excluded_dirs: [vendor, tests]
php_cpd:
enabled: true
excluded_dirs: [vendor, tests]
51 changes: 51 additions & 0 deletions src/Strategies/AudioStrategy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace Jobtech\LaravelChunky\Strategies;

use FFMpeg\Format\Audio\Aac;
use FFMpeg\Format\Audio\Flac;
use FFMpeg\Format\Audio\Mp3;
use FFMpeg\Format\Audio\Vorbis;
use FFMpeg\Format\Audio\Wav;
use Illuminate\Support\Arr;
use Jobtech\LaravelChunky\Strategies\Concerns\ChecksIntegrity;
use Jobtech\LaravelChunky\Strategies\Concerns\HandlesFFMpeg;
use ProtoneMedia\LaravelFFMpeg\FFMpeg\CopyFormat;

class AudioStrategy extends MergeStrategy
{
use ChecksIntegrity,
HandlesFFMpeg;

public function merge()
{
$this->mergeWithFFMpeg();

$this->deleteChunks($this->folder);

return $this->mergeContents();
}

/**
* {@inheritdoc}
*/
public function guessFormat()
{
$extension = strtolower(Arr::last(explode('.', $this->destination())));

switch ($extension) {
case 'aac':
return new Aac;
case 'flac':
return new Flac;
case 'mp3':
return new Mp3;
case 'oog':
return new Vorbis;
case 'wav':
return new Wav;
default:
return new CopyFormat;
}
}
}
46 changes: 46 additions & 0 deletions src/Strategies/Concerns/HandlesFFMpeg.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

namespace Jobtech\LaravelChunky\Strategies\Concerns;

use Illuminate\Support\Arr;
use ProtoneMedia\LaravelFFMpeg\Support\FFMpeg;

trait HandlesFFMpeg
{
public function mergeWithFFMpeg(): void
{
$exporter = FFMpeg::fromDisk($this->manager->chunksFilesystem())
->open($this->mapChunksToArray())
->export()
->inFormat($this->guessFormat())
->concatWithoutTranscoding();

if (! empty($visibility = $this->visibility())) {
$exporter->withVisibility($visibility);
}

$exporter->toDisk(
$this->manager->getMergeDisk()
)->save($this->destination);
}

/**
* Retrieve visibility option.
*
* @return string|null
*/
public function visibility(): ?string
{
return Arr::get(
$this->manager->getMergeOptions(),
'visibility'
);
}

/**
* Guess format from destination file extension.
*
* @return mixed
*/
abstract public function guessFormat();
}
55 changes: 26 additions & 29 deletions src/Strategies/VideoStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,47 @@

namespace Jobtech\LaravelChunky\Strategies;

use FFMpeg\Format\Video\Ogg;
use FFMpeg\Format\Video\WebM;
use FFMpeg\Format\Video\WMV;
use FFMpeg\Format\Video\WMV3;
use FFMpeg\Format\Video\X264;
use Illuminate\Support\Arr;
use Jobtech\LaravelChunky\Strategies\Concerns\ChecksIntegrity;
use ProtoneMedia\LaravelFFMpeg\Support\FFMpeg;
use Jobtech\LaravelChunky\Strategies\Concerns\HandlesFFMpeg;
use ProtoneMedia\LaravelFFMpeg\FFMpeg\CopyFormat;

class VideoStrategy extends MergeStrategy
{
use ChecksIntegrity;
use ChecksIntegrity,
HandlesFFMpeg;

public function merge()
{
$this->handleVideoMerge();
$this->mergeWithFFMpeg();

$this->deleteChunks($this->folder);

return $this->mergeContents();
}

public function handleVideoMerge(): void
public function guessFormat()
{
$exporter = FFMpeg::fromDisk($this->manager->chunksFilesystem())
->open($this->mapChunksToArray())
->export();

$exporter->concatWithoutTranscoding();

if (! empty($visibility = $this->visibility())) {
$exporter->withVisibility($visibility);
$extension = strtolower(Arr::last(explode('.', $this->destination())));

switch ($extension) {
case 'oog':
return new Ogg;
case 'webm':
return new WebM;
case 'wmv':
return new WMV;
case 'wmv3':
return new WMV3;
case 'mp4':
return new X264;
default:
return new CopyFormat;
}

$exporter->toDisk(
$this->manager->getMergeDisk()
)->save($this->destination);
}

/**
* Retrieve visibility option.
*
* @return string|null
*/
public function visibility(): ?string
{
return Arr::get(
$this->manager->getMergeOptions(),
'visibility'
);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Jobtech\LaravelChunky\Tests\Unit\Merge;
namespace Jobtech\LaravelChunky\Tests\Unit\Handlers;

use Jobtech\LaravelChunky\Handlers\MergeHandler;
use Jobtech\LaravelChunky\Strategies\Contracts\MergeStrategy;
Expand Down
80 changes: 80 additions & 0 deletions tests/Unit/Strategies/AudioStrategyTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

namespace Jobtech\LaravelChunky\Tests\Unit\Strategies;

use Illuminate\Support\Facades\Storage;
use Jobtech\LaravelChunky\ChunksManager;
use Jobtech\LaravelChunky\Strategies\AudioStrategy;
use Jobtech\LaravelChunky\Tests\TestCase;

class AudioStrategyTest extends TestCase
{
/**
* @var ChunksManager
*/
private $manager;

protected function setUp(): void
{
parent::setUp();

$this->manager = $this->app->make('chunky');
}

/** @test */
public function strategy_retrieves_visibility_from_options()
{
$mock = $this->mock(ChunksManager::class, function ($mock) {
$mock->shouldReceive('getMergeOptions')
->once()
->andReturn([]);

$mock->shouldReceive('getMergeOptions')
->once()
->andReturn([
'visibility' => 'public',
]);
});

$strategy = new AudioStrategy($mock);

$this->assertNull($strategy->visibility());
$this->assertEquals('public', $strategy->visibility());
}

/** @test */
public function strategy_merges_chunks_without_transcode()
{
$this->manager->chunksFilesystem()->makeDirectory('chunks');

$strategy = new AudioStrategy($this->manager);
$strategy->chunksFolder('resources/mp3');
$strategy->destination('foo/sample.mp3');

$strategy->merge();

Storage::assertExists('foo/sample.mp3');
Storage::assertMissing('chunks/resources/mp3/0_sample.mp3');
Storage::assertMissing('chunks/resources/mp3/1_sample.mp3');
Storage::assertMissing('chunks/resources/mp3/2_sample.mp3');
Storage::assertMissing('chunks/resources/mp3');
}

/** @test */
public function strategy_merges_chunks_with_transcode()
{
$this->manager->chunksFilesystem()->makeDirectory('chunks');

$strategy = new AudioStrategy($this->manager);
$strategy->chunksFolder('resources/mp3');
$strategy->destination('foo/sample.wav');

$strategy->merge();

Storage::assertExists('foo/sample.wav');
Storage::assertMissing('chunks/resources/mp3/0_sample.mp3');
Storage::assertMissing('chunks/resources/mp3/1_sample.mp3');
Storage::assertMissing('chunks/resources/mp3/2_sample.mp3');
Storage::assertMissing('chunks/resources/mp3');
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Jobtech\LaravelChunky\Tests\Unit\Merge\Strategies;
namespace Jobtech\LaravelChunky\Tests\Unit\Strategies;

use Illuminate\Support\Facades\Storage;
use Jobtech\LaravelChunky\Strategies\FlysystemStrategy;
Expand Down

0 comments on commit a019f69

Please sign in to comment.