ReviewOS

also looking at this

meemalabs/laravel-media-converter

[1.0] Introducing the "Simple Usage" API

#14
Merged chris wants to merge v1.0 into main
10 files +406 -200
.github/workflows/test.yml .github/workflows/run-tests.ymlrenamed+17-17
Changes to .github/workflows/run-tests.yml
@@ -1,16 +1,19 @@
1name: Test
1name: Run Tests
22
3on: [push]
3on:
4 push:
5 pull_request:
46
57jobs:
6 test:
8 run-tests:
79 runs-on: ubuntu-latest
810 strategy:
911 fail-fast: false
1012 matrix:
11 php: [7.3, 7.4, 8.0]
13 php: [7.4, 8.0]
1214 laravel: [7.*, 8.*]
13 dependency-version: [prefer-lowest, prefer-stable]
15 dependency-version: [prefer-stable]
16# dependency-version: [prefer-lowest, prefer-stable]
1417 include:
1518 - laravel: 8.*
1619 testbench: 6.*
@@ -21,20 +24,13 @@ jobs:
2124
2225 steps:
2326 - name: Checkout code
24 uses: actions/checkout@v1
27 uses: actions/checkout@v2
2528
2629 - name: Setup PHP
2730 uses: shivammathur/setup-php@v2
2831 with:
2932 php-version: ${{ matrix.php }}
3033 extensions: mbstring, intl, pdo, pdo_sqlite, sqlite, curl
31 env:
32 AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
33 AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
34 AWS_DEFAULT_REGION: 'us-east-1'
35 AWS_MEDIACONVERT_ACCOUNT_URL: ${{ secrets.AWS_MEDIACONVERT_ACCOUNT_URL }}
36 AWS_IAM_ARN: ${{ secrets.AWS_IAM_ARN }}
37 AWS_QUEUE_ARN: ${{ secrets.AWS_QUEUE_ARN }}
3834
3935 - name: Cache dependencies
4036 uses: actions/cache@v1
@@ -44,11 +40,15 @@ jobs:
4440
4541 - name: Install dependencies
4642 run: |
47 composer require "orchestra/testbench:$" --no-interaction --no-update
43 composer require "laravel/framework:$" "orchestra/testbench:$" --no-interaction --no-update
4844 composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction --no-suggest
4945
50 - name: Create .env file
51 run: touch .env # this can be an empty file, just need the test to pass. GitHub Actions uses GitHub Secrets
52
5346 - name: Execute tests
5447 run: vendor/bin/pest
48 env:
49 AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
50 AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
51 AWS_DEFAULT_REGION: 'us-east-1'
52 AWS_MEDIACONVERT_ACCOUNT_URL: ${{ secrets.AWS_MEDIACONVERT_ACCOUNT_URL }}
53 AWS_IAM_ARN: ${{ secrets.AWS_IAM_ARN }}
54 AWS_QUEUE_ARN: ${{ secrets.AWS_QUEUE_ARN }}
CHANGELOG.mdmodified+1-1
Changes to CHANGELOG.md
@@ -2,6 +2,6 @@
22
33All notable changes to `laravel-media-converter` will be documented in this file.
44
5## 1.0.0 - 202X-XX-XX
5## 1.0.0 - 2021-03-15
66
77- initial release
README.mdmodified+9-2
Changes to README.md
@@ -18,13 +18,20 @@ This is a wrapper package for AWS MediaConvert. Additional drivers may be added.
1818use Meema\MediaConverter\Facades\MediaConvert;
1919use Meema\MediaConverter\Jobs\CreateVideoConversion;
2020
21// run any of the following MediaConvert methods:
21# simple usage
22MediaConvert::path('video.mkv') // the s3 path to the file inside the bucket defined in your config (filesystems.disks.s3.bucket)
23 ->optimizeForWeb() // will generate an optmized MP4 for you
24 ->withThumbnails(int $framerateNumerator, int $framerateDenominator, int $maxCaptures, $width = null, $nameModifier = null, $imageQuality = 80) // will generate thumbnails from the video for you, e.g. poster images
25 ->saveTo('my-optimized-video.mp4'); // output file name
26 ->createJob();
27
28# advanced usage
2229$result = MediaConvert::cancelJob(string $id);
2330$result = MediaConvert::createJob(array $settings, array $metaData = [], int $priority = 0);
2431$result = MediaConvert::getJob(string $id);
2532$result = MediaConvert::listJobs(array $options);
2633
27// you may also dispatch a job to convert a video
34# you may also dispatch a job to convert a video
2835dispatch(new CreateVideoConversion($jobSettings, $mediaId)); // $mediaId is optional & refers to the relating model's id
2936```
3037
config/config.phpmodified+1-171
Changes to config/config.php
@@ -65,175 +65,5 @@ return [
6565 */
6666 'statuses_to_track' => ['complete', 'error', 'new_warning', 'progressing', 'status_update', 'input_information', 'queue_hop'],
6767
68 'settings' => [
69 'OutputGroups' => [
70 // thumbnail generation
71 [
72 'CustomName' => 'Thumbnails',
73 'Name' => 'File Group',
74 'Outputs' => [
75 [
76 'ContainerSettings' => [
77 'Container' => 'RAW',
78 ],
79 'VideoDescription' => [
80 'ScalingBehavior' => 'DEFAULT',
81 'TimecodeInsertion' => 'DISABLED',
82 'AntiAlias' => 'ENABLED',
83 'Sharpness' => 50,
84 'CodecSettings' => [
85 'Codec' => 'FRAME_CAPTURE',
86 'FrameCaptureSettings' => [
87 'FramerateNumerator' => null, // to be set dynamically
88 'FramerateDenominator' => null, // to be set dynamically
89 'MaxCaptures' => null, // to be set dynamically
90 'Quality' => 80,
91 ],
92 ],
93 'AfdSignaling' => 'NONE',
94 'DropFrameTimecode' => 'ENABLED',
95 'RespondToAfd' => 'NONE',
96 'ColorMetadata' => 'INSERT',
97 'Width' => null, // to be set dynamically
98 ],
99 'NameModifier' => '.$w$x$h$', // e.g. moderation-test-video.240x136.0000098.jpg
100 ],
101 ],
102 'OutputGroupSettings' => [
103 'Type' => 'FILE_GROUP_SETTINGS',
104 'FileGroupSettings' => [
105 'Destination' => null, // to be set dynamically
106 'DestinationSettings' => [
107 'S3Settings' => [
108 'AccessControl' => [
109 'CannedAcl' => 'PUBLIC_READ',
110 ],
111 ],
112 ],
113 ],
114 ],
115 ],
116
117 // optimize-mp4 output setting
118 [
119 'CustomName' => 'MP4',
120 'Name' => 'File Group',
121 'Outputs' => [
122 [
123 'ContainerSettings' => [
124 'Container' => 'MP4',
125 'Mp4Settings' => [
126 'CslgAtom' => 'INCLUDE',
127 'FreeSpaceBox' => 'EXCLUDE',
128 'MoovPlacement' => 'PROGRESSIVE_DOWNLOAD',
129 ],
130 ],
131 'VideoDescription' => [
132 'ScalingBehavior' => 'DEFAULT',
133 'TimecodeInsertion' => 'DISABLED',
134 'AntiAlias' => 'ENABLED',
135 'Sharpness' => 50,
136 'CodecSettings' => [
137 'Codec' => 'H_264',
138 'H264Settings' => [
139 'InterlaceMode' => 'PROGRESSIVE',
140 'NumberReferenceFrames' => 3,
141 'Syntax' => 'DEFAULT',
142 'Softness' => 0,
143 'GopClosedCadence' => 1,
144 'GopSize' => 90,
145 'Slices' => 1,
146 'GopBReference' => 'DISABLED',
147 'MaxBitrate' => 8000000,
148 'SlowPal' => 'DISABLED',
149 'SpatialAdaptiveQuantization' => 'ENABLED',
150 'TemporalAdaptiveQuantization' => 'ENABLED',
151 'FlickerAdaptiveQuantization' => 'DISABLED',
152 'EntropyEncoding' => 'CABAC',
153 'FramerateControl' => 'INITIALIZE_FROM_SOURCE',
154 'RateControlMode' => 'QVBR',
155 'QvbrSettings' => [
156 'QvbrQualityLevel' => 7,
157 'QvbrQualityLevelFineTune' => 0,
158 ],
159 'CodecProfile' => 'MAIN',
160 'Telecine' => 'NONE',
161 'MinIInterval' => 0,
162 'AdaptiveQuantization' => 'HIGH',
163 'CodecLevel' => 'AUTO',
164 'FieldEncoding' => 'PAFF',
165 'SceneChangeDetect' => 'ENABLED',
166 'QualityTuningLevel' => 'SINGLE_PASS',
167 'FramerateConversionAlgorithm' => 'DUPLICATE_DROP',
168 'UnregisteredSeiTimecode' => 'DISABLED',
169 'GopSizeUnits' => 'FRAMES',
170 'ParControl' => 'INITIALIZE_FROM_SOURCE',
171 'NumberBFramesBetweenReferenceFrames' => 2,
172 'RepeatPps' => 'DISABLED',
173 ],
174 ],
175 'AfdSignaling' => 'NONE',
176 'DropFrameTimecode' => 'ENABLED',
177 'RespondToAfd' => 'NONE',
178 'ColorMetadata' => 'INSERT',
179 ],
180 'AudioDescriptions' => [
181 [
182 'AudioTypeControl' => 'FOLLOW_INPUT',
183 'CodecSettings' => [
184 'Codec' => 'AAC',
185 'AacSettings' => [
186 'AudioDescriptionBroadcasterMix' => 'NORMAL',
187 'Bitrate' => 96000,
188 'RateControlMode' => 'CBR',
189 'CodecProfile' => 'LC',
190 'CodingMode' => 'CODING_MODE_2_0',
191 'RawFormat' => 'NONE',
192 'SampleRate' => 48000,
193 'Specification' => 'MPEG4',
194 ],
195 ],
196 'LanguageCodeControl' => 'FOLLOW_INPUT',
197 ],
198 ],
199 ],
200 ],
201 'OutputGroupSettings' => [
202 'Type' => 'FILE_GROUP_SETTINGS',
203 'FileGroupSettings' => [
204 'Destination' => null, // to be set dynamically
205 'DestinationSettings' => [
206 'S3Settings' => [
207 'AccessControl' => [
208 'CannedAcl' => 'PUBLIC_READ',
209 ],
210 ],
211 ],
212 ],
213 ],
214 ],
215 ],
216 'AdAvailOffset' => 0,
217 'Inputs' => [
218 [
219 'AudioSelectors' => [
220 'Audio Selector 1' => [
221 'Offset' => 0,
222 'DefaultSelection' => 'DEFAULT',
223 'ProgramSelection' => 1,
224 ],
225 ],
226 'VideoSelector' => [
227 'ColorSpace' => 'FOLLOW',
228 ],
229 'FilterEnable' => 'AUTO',
230 'PsiControl' => 'USE_PSI',
231 'FilterStrength' => 0,
232 'DeblockFilter' => 'DISABLED',
233 'DenoiseFilter' => 'DISABLED',
234 'TimecodeSource' => 'EMBEDDED',
235 'FileInput' => null, // to be set dynamically
236 ],
237 ],
238 ],
68 'job_settings' => \Meema\MediaConverter\Helpers\DefaultMediaConvertJobSettings::class,
23969];
src/Contracts/Converter.phpmodified+38-0
Changes to src/Contracts/Converter.php
@@ -4,6 +4,44 @@ namespace Meema\MediaConverter\Contracts;
44
55interface Converter
66{
7 /**
8 * Sets the path of the file input.
9 *
10 * @param string $path
11 * @param string|null $bucket
12 * @return \Meema\MediaConverter\Converters\MediaConvert
13 */
14 public function path(string $path, $bucket = null);
15
16 /**
17 * Generates a web optimized MP4.
18 *
19 * @return \Meema\MediaConverter\Converters\MediaConvert
20 */
21 public function optimizeForWeb();
22
23 /**
24 * Sets the settings required to generate the proper amount of thumbnails.
25 *
26 * @param int $framerateNumerator
27 * @param int $framerateDenominator
28 * @param int $maxCaptures
29 * @param int|null $width
30 * @param string|null $nameModifier
31 * @param int $imageQuality
32 * @return \Meema\MediaConverter\Converters\MediaConvert
33 */
34 public function withThumbnails(int $framerateNumerator, int $framerateDenominator, int $maxCaptures, $width = null, $nameModifier = null, $imageQuality = 80);
35
36 /**
37 * Sets the path & executes the job.
38 *
39 * @param string $s3Path
40 * @param string|null $s3bucket
41 * @return \Aws\Result
42 */
43 public function saveTo(string $s3Path, $s3bucket = null);
44
745 /**
846 * Cancels an active job.
947 *
src/Converters/MediaConvert.phpmodified+96-0
Changes to src/Converters/MediaConvert.php
@@ -15,6 +15,13 @@ class MediaConvert implements Converter
1515 */
1616 protected $client;
1717
18 /**
19 * The MediaConvert job's settings.
20 *
21 * @var array
22 */
23 public array $jobSettings;
24
1825 /**
1926 * Construct converter.
2027 *
@@ -24,6 +31,8 @@ class MediaConvert implements Converter
2431 {
2532 $config = config('media-converter');
2633
34 $this->jobSettings = (new $config['job_settings'])::get();
35
2736 $this->client = new MediaConvertClient([
2837 'version' => $config['version'],
2938 'region' => $config['region'],
@@ -42,6 +51,80 @@ class MediaConvert implements Converter
4251 return $this->client;
4352 }
4453
54 /**
55 * Sets the path of the file input.
56 *
57 * @param string $path - represents the S3 path, e.g path/to/file.mp4
58 * @param string|null $bucket - reference to the S3 Bucket name. Defaults to config value.
59 * @return \Meema\MediaConverter\Converters\MediaConvert
60 */
61 public function path(string $path, $bucket = null): MediaConvert
62 {
63 $this->setFileInput($path, $bucket);
64
65 return $this;
66 }
67
68 /**
69 * Generates a web optimized MP4.
70 *
71 * @return \Meema\MediaConverter\Converters\MediaConvert
72 */
73 public function optimizeForWeb(): MediaConvert
74 {
75 // At the moment, we can simply return $this, because this method is simply used for readability purposes.
76 // The "default job" has all the proper settings already to generate a web optimized mp4.
77 return $this;
78 }
79
80 /**
81 * Sets the settings required to generate the proper amount of thumbnails.
82 *
83 * @param int $framerateNumerator
84 * @param int $framerateDenominator
85 * @param int $maxCaptures
86 * @param int|null $width
87 * @param string|null $nameModifier
88 * @param int $imageQuality
89 * @return \Meema\MediaConverter\Converters\MediaConvert
90 */
91 public function withThumbnails(int $framerateNumerator, int $framerateDenominator, int $maxCaptures, $width = null, $nameModifier = null, $imageQuality = 80): MediaConvert
92 {
93 $this->jobSettings['OutputGroups'][0]['Outputs'][0]['VideoDescription']['CodecSettings']['FrameCaptureSettings'] = [
94 'FramerateNumerator' => $framerateNumerator,
95 'FramerateDenominator' => $framerateDenominator,
96 'MaxCaptures' => $maxCaptures,
97 'Quality' => $imageQuality,
98 ];
99
100 if ($width) {
101 $this->jobSettings['OutputGroups'][0]['Outputs'][0]['VideoDescription']['Width'] = $width;
102 }
103
104 if ($nameModifier) {
105 $this->jobSettings['OutputGroups'][0]['Outputs'][0]['NameModifier'] = $nameModifier;
106 }
107
108 return $this;
109 }
110
111 /**
112 * Sets the S3 path & executes the job.
113 *
114 * @param string $s3Path
115 * @param string|null $s3bucket
116 * @return \Meema\MediaConverter\Converters\MediaConvert
117 */
118 public function saveTo(string $s3Path, $s3bucket = null): MediaConvert
119 {
120 $destination = 's3://'.($s3bucket ?? config('filesystems.disks.s3.bucket'));
121
122 $this->jobSettings['OutputGroups'][0]['OutputGroupSettings']['FileGroupSettings']['Destination'] = $destination.'/thumbnails/';
123 $this->jobSettings['OutputGroups'][1]['OutputGroupSettings']['FileGroupSettings']['Destination'] = $destination.'/mp4/';
124
125 return $this;
126 }
127
45128 /**
46129 * Cancels an active job.
47130 *
@@ -110,4 +193,17 @@ class MediaConvert implements Converter
110193
111194 return 'SECONDS_60'; // gracefully default to this value, in case the config value is missing or incorrect
112195 }
196
197 /**
198 * Sets the S3 input file path.
199 *
200 * @param string $path
201 * @param string|null $bucket
202 */
203 protected function setFileInput(string $path, $bucket = null)
204 {
205 $fileInput = 's3://'.($bucket ?? config('filesystems.disks.s3.bucket')).'/'.$path;
206
207 $this->jobSettings['Inputs'][0]['FileInput'] = $fileInput;
208 }
113209}
src/Facades/MediaConvert.phpmodified+4-0
Changes to src/Facades/MediaConvert.php
@@ -6,6 +6,10 @@ use Illuminate\Support\Facades\Facade;
66
77/**
88 * @method static \Aws\MediaConvert\MediaConvertClient getClient()
9 * @method static \Meema\MediaConverter\Converters\MediaConvert path(string $s3Path, $s3bucket = null)
10 * @method static \Meema\MediaConverter\Converters\MediaConvert optimizeForWeb()
11 * @method static \Meema\MediaConverter\Converters\MediaConvert withThumbnails(int $framerateNumerator, int $framerateDenominator, int $maxCaptures, $width = null, $nameModifier = null, $imageQuality = 80)
12 * @method static \Aws\Result saveTo(string $s3Path, $s3bucket = null)
913 * @method static \Aws\Result cancelJob(string $id)
1014 * @method static \Aws\Result createJob(array $settings, array $metaData = [], int $priority = 0)
1115 * @method static \Aws\Result getJob(string $id)
src/Helpers/DefaultMediaConvertJobSettings.phpadded+178-0
Changes to src/Helpers/DefaultMediaConvertJobSettings.php
@@ -0,0 +1,178 @@
1<?php
2
3namespace Meema\MediaConverter\Helpers;
4
5class DefaultMediaConvertJobSettings
6{
7 public static function get(): array
8 {
9 return [
10 'OutputGroups' => [
11 [
12 'CustomName' => 'Thumbnails',
13 'Name' => 'File Group',
14 'Outputs' => [
15 [
16 'ContainerSettings' => [
17 'Container' => 'RAW',
18 ],
19 'VideoDescription' => [
20 'ScalingBehavior' => 'DEFAULT',
21 'TimecodeInsertion' => 'DISABLED',
22 'AntiAlias' => 'ENABLED',
23 'Sharpness' => 50,
24 'CodecSettings' => [
25 'Codec' => 'FRAME_CAPTURE',
26 'FrameCaptureSettings' => [
27 'FramerateNumerator' => null, // to be set dynamically
28 'FramerateDenominator' => null, // to be set dynamically
29 'MaxCaptures' => null, // to be set dynamically
30 'Quality' => null, // to be set dynamically
31 ],
32 ],
33 'AfdSignaling' => 'NONE',
34 'DropFrameTimecode' => 'ENABLED',
35 'RespondToAfd' => 'NONE',
36 'ColorMetadata' => 'INSERT',
37 'Width' => null, // to be set dynamically
38 ],
39 'NameModifier' => null, // to be set dynamically
40 ],
41 ],
42 'OutputGroupSettings' => [
43 'Type' => 'FILE_GROUP_SETTINGS',
44 'FileGroupSettings' => [
45 'Destination' => null, // to be set dynamically
46 'DestinationSettings' => [
47 'S3Settings' => [
48 'AccessControl' => [
49 'CannedAcl' => 'PUBLIC_READ',
50 ],
51 ],
52 ],
53 ],
54 ],
55 ],
56 [
57 'CustomName' => 'MP4',
58 'Name' => 'File Group',
59 'Outputs' => [
60 [
61 'ContainerSettings' => [
62 'Container' => 'MP4',
63 'Mp4Settings' => [
64 'CslgAtom' => 'INCLUDE',
65 'FreeSpaceBox' => 'EXCLUDE',
66 'MoovPlacement' => 'PROGRESSIVE_DOWNLOAD',
67 ],
68 ],
69 'VideoDescription' => [
70 'ScalingBehavior' => 'DEFAULT',
71 'TimecodeInsertion' => 'DISABLED',
72 'AntiAlias' => 'ENABLED',
73 'Sharpness' => 50,
74 'CodecSettings' => [
75 'Codec' => 'H_264',
76 'H264Settings' => [
77 'InterlaceMode' => 'PROGRESSIVE',
78 'NumberReferenceFrames' => 3,
79 'Syntax' => 'DEFAULT',
80 'Softness' => 0,
81 'GopClosedCadence' => 1,
82 'GopSize' => 90,
83 'Slices' => 1,
84 'GopBReference' => 'DISABLED',
85 'MaxBitrate' => 8000000,
86 'SlowPal' => 'DISABLED',
87 'SpatialAdaptiveQuantization' => 'ENABLED',
88 'TemporalAdaptiveQuantization' => 'ENABLED',
89 'FlickerAdaptiveQuantization' => 'DISABLED',
90 'EntropyEncoding' => 'CABAC',
91 'FramerateControl' => 'INITIALIZE_FROM_SOURCE',
92 'RateControlMode' => 'QVBR',
93 'QvbrSettings' => [
94 'QvbrQualityLevel' => 7,
95 'QvbrQualityLevelFineTune' => 0,
96 ],
97 'CodecProfile' => 'MAIN',
98 'Telecine' => 'NONE',
99 'MinIInterval' => 0,
100 'AdaptiveQuantization' => 'HIGH',
101 'CodecLevel' => 'AUTO',
102 'FieldEncoding' => 'PAFF',
103 'SceneChangeDetect' => 'ENABLED',
104 'QualityTuningLevel' => 'SINGLE_PASS',
105 'FramerateConversionAlgorithm' => 'DUPLICATE_DROP',
106 'UnregisteredSeiTimecode' => 'DISABLED',
107 'GopSizeUnits' => 'FRAMES',
108 'ParControl' => 'INITIALIZE_FROM_SOURCE',
109 'NumberBFramesBetweenReferenceFrames' => 2,
110 'RepeatPps' => 'DISABLED',
111 ],
112 ],
113 'AfdSignaling' => 'NONE',
114 'DropFrameTimecode' => 'ENABLED',
115 'RespondToAfd' => 'NONE',
116 'ColorMetadata' => 'INSERT',
117 ],
118 'AudioDescriptions' => [
119 [
120 'AudioTypeControl' => 'FOLLOW_INPUT',
121 'CodecSettings' => [
122 'Codec' => 'AAC',
123 'AacSettings' => [
124 'AudioDescriptionBroadcasterMix' => 'NORMAL',
125 'Bitrate' => 96000,
126 'RateControlMode' => 'CBR',
127 'CodecProfile' => 'LC',
128 'CodingMode' => 'CODING_MODE_2_0',
129 'RawFormat' => 'NONE',
130 'SampleRate' => 48000,
131 'Specification' => 'MPEG4',
132 ],
133 ],
134 'LanguageCodeControl' => 'FOLLOW_INPUT',
135 ],
136 ],
137 ],
138 ],
139 'OutputGroupSettings' => [
140 'Type' => 'FILE_GROUP_SETTINGS',
141 'FileGroupSettings' => [
142 'Destination' => null, // to be set dynamically
143 'DestinationSettings' => [
144 'S3Settings' => [
145 'AccessControl' => [
146 'CannedAcl' => 'PUBLIC_READ',
147 ],
148 ],
149 ],
150 ],
151 ],
152 ],
153 ],
154 'AdAvailOffset' => 0,
155 'Inputs' => [
156 [
157 'AudioSelectors' => [
158 'Audio Selector 1' => [
159 'Offset' => 0,
160 'DefaultSelection' => 'DEFAULT',
161 'ProgramSelection' => 1,
162 ],
163 ],
164 'VideoSelector' => [
165 'ColorSpace' => 'FOLLOW',
166 ],
167 'FilterEnable' => 'AUTO',
168 'PsiControl' => 'USE_PSI',
169 'FilterStrength' => 0,
170 'DeblockFilter' => 'DISABLED',
171 'DenoiseFilter' => 'DISABLED',
172 'TimecodeSource' => 'EMBEDDED',
173 'FileInput' => null, // to be set dynamically
174 ],
175 ],
176 ];
177 }
178}
tests/MediaConverterTest.phpmodified+55-3
Changes to tests/MediaConverterTest.php
@@ -10,11 +10,63 @@ beforeEach(function () {
1010});
1111
1212it('can successfully initialize settings', function () {
13 $this->assertTrue(is_array($this->settings));
13 $converter = MediaConvert::path('my-video.mkv', 'test-bucket');
14 $this->assertTrue(is_array($converter->jobSettings));
15});
16
17it('can successfully set a path', function () {
18 $converter = MediaConvert::path('my-video.mkv', 'test-bucket');
19 $fileInput = 's3://test-bucket/my-video.mkv';
20 $this->assertEquals($converter->jobSettings['Inputs'][0]['FileInput'], $fileInput);
21});
22
23it('can successfully web optimize a video', function () {
24 $converter = MediaConvert::path('my-video.mkv', 'test-bucket')->optimizeForWeb();
25 // todo: we could likely improve this by running an actual test and compare the output file
26 $this->assertEquals($converter->jobSettings['OutputGroups'][1]['CustomName'], 'MP4');
27});
28
29it('can successfully set the settings to generate thumbnails', function () {
30 $framerateNumerator = 1;
31 $framerateDenominator = 2;
32 $maxCaptures = 3;
33 $imageQuality = 75;
34 $width = 100;
35 $nameModifier = '.$w$x$h$';
36
37 $converter = MediaConvert::path('my-video.mkv', 'test-bucket')
38 ->optimizeForWeb()
39 ->withThumbnails($framerateNumerator, $framerateDenominator, $maxCaptures, $width, $nameModifier, $imageQuality);
40
41 $this->assertEquals($converter->jobSettings['OutputGroups'][0]['Outputs'][0]['VideoDescription']['CodecSettings']['FrameCaptureSettings'], [
42 'FramerateNumerator' => $framerateNumerator,
43 'FramerateDenominator' => $framerateDenominator,
44 'MaxCaptures' => $maxCaptures,
45 'Quality' => $imageQuality,
46 ]);
47
48 $this->assertEquals($converter->jobSettings['OutputGroups'][0]['Outputs'][0]['VideoDescription']['Width'], $width);
49 $this->assertEquals($converter->jobSettings['OutputGroups'][0]['Outputs'][0]['NameModifier'], $nameModifier);
50});
51
52it('can successfully update the output path', function () {
53 $inputName = 'my-video.mkv';
54 $outputName = 'my-video.mp4';
55 $bucket = 'test-bucket';
56
57 $converter = MediaConvert::path($inputName, 'test-bucket')
58 ->optimizeForWeb()
59 ->withThumbnails(1, 2, 3, 100)
60 ->saveTo($outputName, $bucket);
61
62 $destination = 's3://test-bucket';
63
64 $this->assertEquals($converter->jobSettings['OutputGroups'][0]['OutputGroupSettings']['FileGroupSettings']['Destination'], $destination.'/thumbnails/');
65 $this->assertEquals($converter->jobSettings['OutputGroups'][1]['OutputGroupSettings']['FileGroupSettings']['Destination'], $destination.'/mp4/');
1466});
1567
1668it('can successfully create a job', function () {
17 $response = MediaConvert::createJob($this->settings);
69 $response = MediaConvert::createJob($this->jobSettings);
1870
1971 $this->assertEquals($response['@metadata']['statusCode'], 201);
2072});
@@ -30,7 +82,7 @@ it('can successfully get a job', function () {
3082});
3183
3284 it('can successfully cancel a job', function () {
33 $job = MediaConvert::createJob($this->settings, []);
85 $job = MediaConvert::createJob($this->jobSettings, []);
3486
3587 $response = MediaConvert::cancelJob($job['Job']['Id']);
3688
tests/MediaConverterTestCase.phpmodified+7-6
Changes to tests/MediaConverterTestCase.php
@@ -8,9 +8,7 @@ use Orchestra\Testbench\TestCase;
88
99class MediaConverterTestCase extends TestCase
1010{
11 public $settings = [];
12
13 public $sizes = [];
11 public $jobSettings = [];
1412
1513 protected function getPackageProviders($app): array
1614 {
@@ -19,14 +17,16 @@ class MediaConverterTestCase extends TestCase
1917
2018 public function initializeDotEnv()
2119 {
20 if (! file_exists(__DIR__.'/../.env')) {
21 return;
22 }
23
2224 $dotenv = \Dotenv\Dotenv::createImmutable(dirname(__DIR__));
2325 $dotenv->load();
2426 }
2527
2628 public function initializeSettings()
2729 {
28 $configFile = file_get_contents(__DIR__.'/config/job.json');
29
3030 // let's make sure these config values are set
3131 Config::set('media-converter.credentials.key', env('AWS_ACCESS_KEY_ID'));
3232 Config::set('media-converter.credentials.secret', env('AWS_SECRET_ACCESS_KEY'));
@@ -34,6 +34,7 @@ class MediaConverterTestCase extends TestCase
3434 Config::set('media-converter.iam_arn', env('AWS_IAM_ARN'));
3535 Config::set('media-converter.queue_arn', env('AWS_QUEUE_ARN'));
3636
37 $this->settings = json_decode($configFile, true);
37 $configFile = file_get_contents(__DIR__.'/config/job.json');
38 $this->jobSettings = json_decode($configFile, true);
3839 }
3940}