Skip to content

Commit

Permalink
### Added
Browse files Browse the repository at this point in the history
- Added a summary option to `getFileInfo()`

### Changed
- Refactored the `config.php` options to be more consistent
  • Loading branch information
khalwat committed Mar 7, 2017
1 parent c48bc3f commit 6b99c5b
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 26 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Transcoder Changelog

## 1.0.2 - 2017.03.07
### Added
- Added a summary option to `getFileInfo()`

### Changed
- Refactored the `config.php` options to be more consistent

## 1.0.1 - 2017.03.06
### Added
- Added `height` and `width` options for resizing the videos
Expand Down
32 changes: 24 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ It will return to you a URL to the transcoded video if it already exists, or if
In the array you pass in, the default values are used if the key/value pair does not exist:

{
"videoFormat" => "mp4",
"videoEncoder" => "h264",
"videoBitRate" => "800k",
"videoFrameRate" => 15,
"aspectRatio" => "letterbox",
Expand Down Expand Up @@ -102,7 +102,7 @@ You can control the color of the letterboxed area (it's `black` by default) via

The `sharpen` option determines whether an unsharp mask filter should be applied to the scaled video.

The file format setting `videoFormat` is preset to what you'll need to generate `mp4` videos, but it can also generate `webm` videos, or any other format that `ffmpeg` supports. See the `config.php` file for details
The file format setting `videoEncoder` is preset to what you'll need to generate `h264` videos, but it can also generate `webm` videos, or any other format that `ffmpeg` supports. See the `config.php` file for details

### Generating a Transcoded Audio File

Expand All @@ -128,7 +128,7 @@ It will return to you a URL to the transcoded audio file if it already exists, o
In the array you pass in, the default values are used if the key/value pair does not exist:

{
"audioFormat" => "mp3",
"audioEncoder" => "mp3",
"audioBitRate" => "128k",
"audioSampleRate" => "44100",
"audioChannels" => "2",
Expand All @@ -146,7 +146,7 @@ If you want to have the Transcoder not change a parameter, pass in an empty valu

The above example would cause it to not change the audio of the source audio file at all (not recommended for client-proofing purposes).

The file format setting `audioFormat` is preset to what you'll need to generate `mp3` audio files, but it can also generate `m4a`, `ogg`, or any other format that `ffmpeg` supports. See the `config.php` file for details
The file format setting `audioEncoder` is preset to what you'll need to generate `mp3` audio files, but it can also generate `aac`, `ogg`, or any other format that `ffmpeg` supports. See the `config.php` file for details

### Getting Transcoding Progress

Expand Down Expand Up @@ -242,14 +242,31 @@ The `sharpen` option determines whether an unsharp mask filter should be applied

To get information about an existing video/audio file, you can use `craft.transcoder.getFileInfo()`:

{% set fileInfo = craft.transcoder.getFileInfo('/home/vagrant/sites/nystudio107/public/oceans.mp4') %}
{% set fileInfo = craft.transcoder.getFileInfo('/home/vagrant/sites/nystudio107/public/oceans.mp4', true) %}

You can also pass in an `Asset`:

{% set myAsset = entry.someAsset.first() %}
{% set fileInfo = craft.transcoder.getFileInfo(myAsset) %}
{% set fileInfo = craft.transcoder.getFileInfo(myAsset, true) %}

This returns an array with two top-level keys:
By passing in `true` as the second argument, we get just a summary of the video/audio file information in an array:

[
'videoEncoder' => 'h264'
'videoBitRate' => '3859635'
'videoFrameRate' => 23.976023976024
'height' => 400
'width' => 960
'audioEncoder' => 'aac'
'audioBitRate' => '92926'
'audioSampleRate' => '48000'
'audioChannels' => 2
'filename' => '/htdocs/craft3/public/assets/oceans.mp4'
'duration' => '46.613333'
'size' => '23014356'
]

If you instead pass in `false` as the second parameter (or omit it), then `craft.transcoder.getFileInfo()` returns the full video/audio file info an array with two top-level keys:

* `format` - information about the container file format
* `streams` - information about each stream in the container; many videos have multiple streams, for instance, one for the video streams, and another for the audio stream. There can even be multiple video or audio streams in a container.
Expand Down Expand Up @@ -387,7 +404,6 @@ The file must reside in the webroot (thus a URL or URI must be passed in as a pa

Some things to do, and ideas for potential features:

* Add a simpler way to extract the most common video/audio info from a file
* Add a console command for doing encodings via console
* Figure out a way to reliably do multi-pass video encoding
* Add audio normalization via `loudnorm` http://k.ylo.ph/2016/04/04/loudnorm.html
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "nystudio107/craft3-transcoder",
"description": "Transcode video & audio files to various formats, and provide video thumbnails",
"type": "craft-plugin",
"version": "1.0.1",
"version": "1.0.2",
"keywords": [
"craft",
"cms",
Expand Down
13 changes: 9 additions & 4 deletions src/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,17 @@

// Preset video encoders
"videoEncoders" => [
"mp4" => [
"h264" => [
"fileSuffix" => ".mp4",
"fileFormat" => "mp4",
"videoCodec" => "libx264",
"videoCodecOptions" => "-vprofile high -preset slow -crf 22",
"audioCodec" => "libfdk_aac",
"audioCodecOptions" => "-async 1000",
],
"webm" => [
"fileSuffix" => ".webm",
"fileFormat" => "webm",
"videoCodec" => "libvpx",
"videoCodecOptions" => "-quality good -cpu-used 0",
"audioCodec" => "libvorbis",
Expand All @@ -65,17 +67,20 @@
"audioEncoders" => [
"mp3" => [
"fileSuffix" => ".mp3",
"fileFormat" => "mp3",
"audioCodec" => "libmp3lame",
"audioCodecOptions" => "",
],
"m4a" => [
"aac" => [
"fileSuffix" => ".m4a",
"fileFormat" => "aac",
"audioCodec" => "libfdk_aac",
"audioCodecOptions" => "",

],
"ogg" => [
"fileSuffix" => ".ogg",
"fileFormat" => "ogg",
"audioCodec" => "libvorbis",
"audioCodecOptions" => "",
],
Expand All @@ -84,7 +89,7 @@
// Default options for encoded videos
"defaultVideoOptions" => [
// Video settings
"videoFormat" => "mp4",
"videoEncoder" => "h264",
"videoBitRate" => "800k",
"videoFrameRate" => 15,
// Audio settings
Expand Down Expand Up @@ -114,7 +119,7 @@

// Default options for encoded videos
"defaultAudioOptions" => [
"audioFormat" => "mp3",
"audioEncoder" => "mp3",
"audioBitRate" => "128k",
"audioSampleRate" => "44100",
"audioChannels" => "2",
Expand Down
84 changes: 73 additions & 11 deletions src/services/Transcoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

use Craft;
use craft\base\Component;
use craft\console\Request;
use craft\elements\Asset;
use craft\volumes\Local;

Expand Down Expand Up @@ -41,12 +40,34 @@ class Transcoder extends Component

// Params that should be excluded from being part of the generated filename
protected $excludeParams = [
'videoFormat',
'audioFormat',
'videoEncoder',
'audioEncoder',
'fileSuffix',
'sharpen'
];

// Mappings for getFileInfo() summary values
protected $infoSummary = [
'format' => [
'filename' => 'filename',
'duration' => 'duration',
'size' => 'size',
],
'audio' => [
'codec_name' => 'audioEncoder',
'bit_rate' => 'audioBitRate',
'sample_rate' => 'audioSampleRate',
'channels' => 'audioChannels',
],
'video' => [
'codec_name' => 'videoEncoder',
'bit_rate' => 'videoBitRate',
'avg_frame_rate' => 'videoFrameRate',
'height' => 'height',
'width' => 'width',
],
];

// Public Methods
// =========================================================================

Expand All @@ -72,7 +93,7 @@ public function getVideoUrl($filePath, $videoOptions): string

// Get the video encoder presets to use
$videoEncoders = Craft::$app->config->get("videoEncoders", "transcoder");
$thisEncoder = $videoEncoders[$videoOptions['videoFormat']];
$thisEncoder = $videoEncoders[$videoOptions['videoEncoder']];

$videoOptions['fileSuffix'] = $thisEncoder['fileSuffix'];

Expand Down Expand Up @@ -135,7 +156,7 @@ public function getVideoUrl($filePath, $videoOptions): string
// Assemble the destination path and final ffmpeg command
$destVideoPath = $destVideoPath.$destVideoFile;
$ffmpegCmd .= ' -f '
.$videoOptions['videoFormat']
.$thisEncoder['fileFormat']
.' -y '.escapeshellarg($destVideoPath)
.' 1> '.$progressFile.' 2>&1 & echo $!';

Expand Down Expand Up @@ -249,7 +270,7 @@ public function getAudioUrl($filePath, $audioOptions): string

// Get the audio encoder presets to use
$audioEncoders = Craft::$app->config->get("audioEncoders", "transcoder");
$thisEncoder = $audioEncoders[$audioOptions['audioFormat']];
$thisEncoder = $audioEncoders[$audioOptions['audioEncoder']];

$audioOptions['fileSuffix'] = $thisEncoder['fileSuffix'];

Expand Down Expand Up @@ -289,7 +310,7 @@ public function getAudioUrl($filePath, $audioOptions): string
// Assemble the destination path and final ffmpeg command
$destAudioPath = $destAudioPath.$destAudioFile;
$ffmpegCmd .= ' -f '
.$audioOptions['audioFormat']
.$thisEncoder['fileFormat']
.' -y '.escapeshellarg($destAudioPath)
.' 1> '.$progressFile.' 2>&1 & echo $!';

Expand Down Expand Up @@ -325,11 +346,12 @@ public function getAudioUrl($filePath, $audioOptions): string
/**
* Extract information from a video/audio file
*
* @param $filePath
* @param $filePath
* @param bool $summary
*
* @return array
*/
public function getFileInfo($filePath): array
public function getFileInfo($filePath, $summary = false): array
{

$result = null;
Expand All @@ -346,6 +368,46 @@ public function getFileInfo($filePath): array
Craft::info($ffprobeCmd, __METHOD__);
$result = json_decode($shellOutput, true);
Craft::info(print_r($result, true), __METHOD__);

// Trim down the arrays to just a summary
if ($summary && !empty($result)) {
$summaryResult = [];
foreach ($result as $topLevelKey => $topLevelValue) {
switch ($topLevelKey) {
// Format info
case "format":
foreach ($this->infoSummary['format'] as $settingKey => $settingValue) {
if (!empty($topLevelValue[$settingKey])) {
$summaryResult[$settingValue] = $topLevelValue[$settingKey];
}
}
break;
// Stream info
case "streams":
foreach ($topLevelValue as $stream) {
$infoSummaryType = $stream['codec_type'];
foreach ($this->infoSummary[$infoSummaryType] as $settingKey => $settingValue) {
if (!empty($stream[$settingKey])) {
$summaryResult[$settingValue] = $stream[$settingKey];
}
}

}
break;
// Unknown info
default:
break;
}
}
// Handle cases where the framerate is returned as XX/YY
if (!empty($summaryResult['videoFrameRate'])
&& (strpos($summaryResult['videoFrameRate'], '/') !== false)
) {
$parts = explode('/', $summaryResult['videoFrameRate']);
$summaryResult['videoFrameRate'] = floatval($parts[0]) / floatval($parts[1]);
}
$result = $summaryResult;
}
}

return $result;
Expand All @@ -365,7 +427,7 @@ public function getVideoFilename($filePath, $videoOptions): string

// Get the video encoder presets to use
$videoEncoders = Craft::$app->config->get("videoEncoders", "transcoder");
$thisEncoder = $videoEncoders[$videoOptions['videoFormat']];
$thisEncoder = $videoEncoders[$videoOptions['videoEncoder']];

$videoOptions['fileSuffix'] = $thisEncoder['fileSuffix'];

Expand All @@ -388,7 +450,7 @@ public function getAudioFilename($filePath, $audioOptions): string

// Get the video encoder presets to use
$audioEncoders = Craft::$app->config->get("audioEncoders", "transcoder");
$thisEncoder = $audioEncoders[$audioOptions['audioFormat']];
$thisEncoder = $audioEncoders[$audioOptions['audioEncoder']];

$audioOptions['fileSuffix'] = $thisEncoder['fileSuffix'];

Expand Down
4 changes: 2 additions & 2 deletions src/variables/TranscoderVariable.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ public function getAudioUrl($filePath, $audioOptions): string
*
* @return array
*/
public function getFileInfo($filePath): array
public function getFileInfo($filePath, $summary = false): array
{
$result = Transcoder::$plugin->transcoder->getFileInfo($filePath);
$result = Transcoder::$plugin->transcoder->getFileInfo($filePath, $summary);

return $result;
}
Expand Down

0 comments on commit 6b99c5b

Please sign in to comment.