Skip to content

Commit 84aee05

Browse files
committed
Merge branch 'feature/update_ffmpeg' into develop
2 parents ae846d5 + a7541ba commit 84aee05

File tree

5 files changed

+65
-36
lines changed

5 files changed

+65
-36
lines changed

Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM sportarc/cloudtranscode-base:3.3
1+
FROM sportarc/cloudtranscode-base:4.2
22
MAINTAINER bFAN Sports
33

44
COPY . /usr/src/cloudtranscode

README.md

+15-15
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/sportarchive/CloudTranscode?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
22
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/sportarchive/CloudTranscode/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/sportarchive/CloudTranscode/?branch=master)
33

4-
### Updates 2018/10/17
5-
Cleaning up the doc. Fixed an issue. Trying to make the documentation more accessible.
4+
### Updates 2020/05/09
5+
Update to FFMpeg 4.2
66

77
# What is Cloud Transcode?
88
Cloud Transcode (CT) is your own distributed transcoding stack. With it you can transcode media files in a distributed way, at scale.
@@ -42,13 +42,13 @@ Those Activities listen to the Amazon SFN (Step functions) service for incoming
4242
Tasks and Workflows (aka `State Machine`) are defined in the AWS SFN console, and are identified by their AWS ARNs (AWS resources identifier). You can then start `N` activity workers that will start listening for incoming jobs and execute them.
4343

4444
You can scale your infrastructure in AWS based on your volume, capacity, cost, resources, etc.
45-
You can run those SFN Activities on Docker, which is recommended. A Dockerfile is provided for you.
45+
You can run those SFN Activities on Docker, which is recommended. A Dockerfile is provided for you.
4646
But you can run on anything and anywhere.
4747

4848
Your client applications can initiate new SFN workflows using the AWS SDK of your choice. The client apps will pass JSON input date to AWS SFN. <br>
4949
SFN will then pass this input to your activities, which will then return a JSON output. This output can be passed on to the next activities.
5050

51-
Thanks to the `CloudProcessingEngine-SDK` you can build your own workflow and call any activities you want. You can implement your own activities as well.
51+
Thanks to the `CloudProcessingEngine-SDK` you can build your own workflow and call any activities you want. You can implement your own activities as well.
5252

5353
Cloud Transcode could use help on the following Activities if you are interested in participating:
5454

@@ -87,16 +87,16 @@ One TranscodeAssetActivity worker processes all outputs wanted, in sequence, not
8787

8888
Activities are standalone scripts writen in PHP (legacy reasons, but it's clean!) that can be started in command line.
8989

90-
```
90+
```
9191
bash $> ./src/activities/ValidateAssetActivity.php -A arn:aws:states:eu-west-1:XXXXXXXXXXXX:activity:ValidateAsset
9292
bash $> ./src/activities/TranscodeAssetActivity.php -A arn:aws:states:eu-west-1:XXXXXXXXXXXX:activity:TranscodeAsset
9393
```
9494

9595
Or using Docker
9696

9797
```
98-
$> sudo docker run sportarc/cloudtranscode ValidateAssetActivity -A arn:aws:states:eu-west-1:XXXXXXXXXXXX:activity:ValidateAsset
99-
$> sudo docker run sportarc/cloudtranscode TranscodeAssetActivity -A arn:aws:states:eu-west-1:XXXXXXXXXXXX:activity:TranscodeAsset
98+
$> sudo docker run sportarc/cloudtranscode:4.2 ValidateAssetActivity -A arn:aws:states:eu-west-1:XXXXXXXXXXXX:activity:ValidateAsset
99+
$> sudo docker run sportarc/cloudtranscode:4.2 TranscodeAssetActivity -A arn:aws:states:eu-west-1:XXXXXXXXXXXX:activity:TranscodeAsset
100100
```
101101

102102
Using these commands, you can start an activity worker that processes one type of activity. In these cases `ValidateAssetActivity` and `TranscodeAssetActivity`
@@ -128,7 +128,7 @@ A Dockerfile like this for example:
128128

129129

130130
``` Dockerfile
131-
FROM sportarc/cloudtranscode:3.3
131+
FROM sportarc/cloudtranscode:4.2
132132
MAINTAINER bFAN Sports
133133

134134
COPY clientInterfaces /usr/src/clientInterfaces
@@ -140,10 +140,10 @@ Then build your own image as follow: `sudo docker build -t sportarc/cloudtransco
140140
Then you can start your workers like this:
141141

142142
```
143-
$> sudo docker run sportarc/cloudtranscode-prod ValidateAssetActivity -A arn:aws:states:eu-west-1:XXXXXXXXXXXX:activity:ValidateAsset -C /usr/src/clientInterfaces/ValidateAssetClientInterfaces.php
144-
$> sudo docker run sportarc/cloudtranscode-prod TranscodeAssetActivity -A arn:aws:states:eu-west-1:XXXXXXXXXXXX:activity:TranscodeAllOutputAssets -C /usr/src/clientInterfaces/TranscodeAllOutputAssetsClientInterfaces.php
145-
$> sudo docker run sportarc/cloudtranscode-prod TranscodeAssetActivity -A arn:aws:states:eu-west-1:XXXXXXXXXXXX:activity:TranscodeImageAsset -C /usr/src/clientInterfaces/TranscodeImagesAssetsClientInterfaces.php
146-
$> sudo docker run sportarc/cloudtranscode-prod TranscodeAssetActivity -A arn:aws:states:eu-west-1:XXXXXXXXXXXX:activity:OnDemandTranscodeAsset -C /usr/src/clientInterfaces/OnDemandTranscodeAssetClientInterfaces.php
143+
$> sudo docker run sportarc/cloudtranscode-prod:4.2 ValidateAssetActivity -A arn:aws:states:eu-west-1:XXXXXXXXXXXX:activity:ValidateAsset -C /usr/src/clientInterfaces/ValidateAssetClientInterfaces.php
144+
$> sudo docker run sportarc/cloudtranscode-prod:4.2 TranscodeAssetActivity -A arn:aws:states:eu-west-1:XXXXXXXXXXXX:activity:TranscodeAllOutputAssets -C /usr/src/clientInterfaces/TranscodeAllOutputAssetsClientInterfaces.php
145+
$> sudo docker run sportarc/cloudtranscode-prod:4.2 TranscodeAssetActivity -A arn:aws:states:eu-west-1:XXXXXXXXXXXX:activity:TranscodeImageAsset -C /usr/src/clientInterfaces/TranscodeImagesAssetsClientInterfaces.php
146+
$> sudo docker run sportarc/cloudtranscode-prod:4.2 TranscodeAssetActivity -A arn:aws:states:eu-west-1:XXXXXXXXXXXX:activity:OnDemandTranscodeAsset -C /usr/src/clientInterfaces/OnDemandTranscodeAssetClientInterfaces.php
147147
```
148148

149149
As you can see, you can create many SFN tasks. Each task will execute the same activity code, but they are connected to different client applications using different Interface classes.
@@ -227,12 +227,12 @@ Thanks for contributing !
227227

228228
# FFmpeg
229229

230-
CloudTranscode uses FFmpeg 3.3
230+
CloudTranscode uses FFmpeg 4.2
231231

232232
The CloudTranscode Docker image is based on two other images:
233233

234-
- https://hub.docker.com/r/sportarc/ffmpeg/: Base image containing: Ubuntu 14, PHP CLI 5.6, FFmpeg
235-
- https://hub.docker.com/r/sportarc/cloudtranscode-base/: Adds `ImageMagic` to the above image
234+
- https://hub.docker.com/r/sportarc/ffmpeg/
235+
- https://hub.docker.com/r/sportarc/cloudtranscode-base/
236236

237237

238238
# FFMpeg performance benchmark on Amazon EC2

src/activities/ValidateAssetActivity.php

+41-16
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<?php
44

55
/*
6-
* This class validate input assets and get mime type and metadata
6+
* This class validate input assets and get mime type and metadata
77
* Using the ValidateAsset activity you can confirm your asset can be transcoded
88
*
99
* Copyright (C) 2016 BFan Sports - Sport Archive Inc.
@@ -32,15 +32,17 @@ class ValidateAssetActivity extends BasicActivity
3232
private $finfo;
3333
private $s3;
3434
private $curl_data = '';
35-
35+
36+
const VALIDATE_ASSET_FAILED = "VALIDATE_ASSET_FAILED";
37+
3638
public function __construct($client = null, $params, $debug, $cpeLogger)
3739
{
3840
# Check if preper env vars are setup
3941
if (!($region = getenv("AWS_DEFAULT_REGION")))
4042
throw new CpeSdk\CpeException("Set 'AWS_DEFAULT_REGION' environment variable!");
41-
43+
4244
parent::__construct($client, $params, $debug, $cpeLogger);
43-
45+
4446
$this->s3 = new \Aws\S3\S3Client([
4547
"version" => "latest",
4648
"region" => $region
@@ -51,17 +53,17 @@ public function __construct($client = null, $params, $debug, $cpeLogger)
5153
private function writefn($ch, $chunk)
5254
{
5355
static $limit = 1024; // 500 bytes, it's only a test
54-
56+
5557
$len = strlen($this->curl_data) + strlen($chunk);
5658
if ($len >= $limit ) {
5759
$this->curl_data .= substr($chunk, 0, $limit-strlen($this->curl_data));
5860
return -1;
5961
}
60-
62+
6163
$this->curl_data .= $chunk;
6264
return strlen($chunk);
6365
}
64-
66+
6567
// Perform the activity
6668
public function process($task)
6769
{
@@ -74,21 +76,44 @@ public function process($task)
7476

7577
// Call parent process:
7678
parent::process($task);
77-
79+
7880
$this->activityHeartbeat();
7981
$tmpFile = tempnam(sys_get_temp_dir(), 'ct');
8082

8183
if (isset($this->input->{'input_asset'}->{'http'})) {
84+
$this->cpeLogger->logOut(
85+
"DEBUG",
86+
basename(__FILE__),
87+
"Downloading first 1024 bytes from: " . $this->input->{'input_asset'}->{'http'},
88+
$this->logKey
89+
);
90+
8291
$ch = curl_init();
8392
curl_setopt($ch, CURLOPT_URL, $this->input->{'input_asset'}->{'http'});
8493
curl_setopt($ch, CURLOPT_RANGE, '0-1024');
8594
curl_setopt($ch, CURLOPT_WRITEFUNCTION, array($this, 'writefn'));
8695
curl_exec($ch);
8796
curl_close($ch);
97+
98+
if ($errno = curl_errno($ch)) {
99+
$error_message = curl_strerror($errno);
100+
throw new CpeSdk\CpeException(
101+
$error_message,
102+
self::VALIDATE_ASSET_FAILED
103+
);
104+
}
105+
88106
$chunk = $this->curl_data;
89107
}
90108
else if (isset($this->input->{'input_asset'}->{'bucket'}) &&
91109
isset($this->input->{'input_asset'}->{'file'})) {
110+
$this->cpeLogger->logOut(
111+
"DEBUG",
112+
basename(__FILE__),
113+
"Downloading first 1024 bytes from S3. Bucket: " . $this->input->{'input_asset'}->{'bucket'} . ". Key: " . $this->input->{'input_asset'}->{'file'},
114+
$this->logKey
115+
);
116+
92117
// Fetch first 1 KiB of the file for Magic number validation
93118
$obj = $this->s3->getObject([
94119
'Bucket' => $this->input->{'input_asset'}->{'bucket'},
@@ -97,7 +122,7 @@ public function process($task)
97122
]);
98123
$chunk = (string) $obj['Body'];
99124
}
100-
125+
101126
$this->activityHeartbeat();
102127

103128
// Determine file type
@@ -112,7 +137,7 @@ public function process($task)
112137
basename(__FILE__),
113138
"File meta information gathered. Mime: $mime | Type: $type",
114139
$this->logKey
115-
);
140+
);
116141

117142
// Load the right transcoder base on input_type
118143
// Get asset detailed info
@@ -147,14 +172,14 @@ public function process($task)
147172
}
148173
}
149174
}
150-
175+
151176
$assetInfo->mime = $mime;
152177
$assetInfo->type = $type;
153178

154179
$result['input_asset'] = $this->input->{'input_asset'};
155180
$result['input_metadata'] = $assetInfo;
156181
$result['output_assets'] = $this->input->{'output_assets'};
157-
182+
158183
return json_encode($result);
159184
}
160185
}
@@ -188,11 +213,11 @@ function check_activity_arguments()
188213
global $debug;
189214
global $clientClassPath;
190215
global $name;
191-
216+
192217
// Handle input parameters
193218
if (!($options = getopt("N:A:l:C:hd")))
194219
usage();
195-
220+
196221
if (isset($options['h']))
197222
usage();
198223

@@ -216,7 +241,7 @@ function check_activity_arguments()
216241
if (isset($options['N']) && $options['N']) {
217242
$name = $options['N'];
218243
}
219-
244+
220245
if (isset($options['l']))
221246
$logPath = $options['l'];
222247
}
@@ -251,4 +276,4 @@ function check_activity_arguments()
251276

252277
// Initiate the polling loop and will call your `process` function upon trigger
253278
// The process will exit after 24 hours (1440 minutes)
254-
$activityPoller->doActivity(1440);
279+
$activityPoller->doActivity(1440);

src/activities/transcoders/BasicTranscoder.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ public function getAssetInfo($inputFilePath)
102102
"Execution of command '".$ffprobeCmd."' failed.",
103103
$this->activityLogKey
104104
);
105-
return false;
105+
106+
throw new CpeSdk\CpeException("Unable to execute FFProbe to get information about '$inputFilePath'!",
107+
self::EXEC_VALIDATE_FAILED);
106108
}
107109

108110
if (empty($out)) {

src/utils/CommandExecuter.php

+5-3
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public function execute(
3737
{
3838
if ($logKey)
3939
$this->logKey = $logKey;
40-
40+
4141
$this->cpeLogger->logOut("INFO", basename(__FILE__), "Executing: $cmd", $this->logKey);
4242

4343
// Start execution of $cmd
@@ -95,7 +95,7 @@ public function execute(
9595
echo ".";
9696
flush();
9797
}
98-
98+
9999
// Read prog output
100100
if (isset($pipes[1]) && $pipes[1]) {
101101
$out = stream_get_contents($pipes[1], -1);
@@ -122,10 +122,12 @@ public function execute(
122122
basename(__FILE__),
123123
"Can't execute: $cmd. Exit Code: ".$procStatus['exitcode'],
124124
$this->logKey);
125-
if ($allOut)
125+
if ($allOut) {
126126
$this->cpeLogger->logOut("ERROR",
127127
basename(__FILE__), "COMMAND STDOUT: ".$allOut,
128128
$this->logKey);
129+
$allOut = null;
130+
}
129131
if ($allOutErr)
130132
$this->cpeLogger->logOut("ERROR",
131133
basename(__FILE__), "COMMAND STDERR: ".$allOutErr,

0 commit comments

Comments
 (0)