|
<?php |
|
//Not everything will work out of the box for you, as this is just for our application. |
|
//Framework Laravel |
|
|
|
namespace Modules\Caption\Services; |
|
|
|
//https://github.com/captioning/captioning |
|
use Captioning\Format\WebvttFile; |
|
use ilos\Models\Caption\CaptionRequest; |
|
use Exception; |
|
use stdClass; |
|
|
|
/** |
|
* Class CaptionAmazonService |
|
* @package Modules\Caption\Factories\Implementation |
|
*/ |
|
class CaptionAmazonService |
|
{ |
|
/** |
|
* Paragraphs will be split in BLOCK_DURATION seconds |
|
*/ |
|
const BLOCK_DURATION = 2; |
|
/** |
|
* |
|
*/ |
|
const ITEM_TYPE_PUNCTUATION = 'punctuation'; |
|
|
|
/** |
|
* @var WebvttFile |
|
*/ |
|
private $webvttFile; |
|
|
|
/** |
|
* CaptionAmazonService constructor. |
|
* @param WebvttFile $webvttFile |
|
*/ |
|
public function __construct(WebvttFile $webvttFile) { |
|
$this->webvttFile = $webvttFile; |
|
} |
|
|
|
/** |
|
* @param CaptionRequest $captionRequest |
|
* @param stdClass $contents |
|
* @return mixed|null |
|
* @throws Exception |
|
*/ |
|
public function createCaptionFileFromBlocks(CaptionRequest $captionRequest, stdClass $contents) { |
|
|
|
$duration = self::BLOCK_DURATION; |
|
$blockNumber = 1; |
|
$blocks = []; |
|
|
|
if(!isset($contents->results->items)){ |
|
return null; |
|
} |
|
|
|
foreach($contents->results->items as $key => $item) { |
|
$isPunctuationItem = $this->isPunctuationItem($item); |
|
|
|
if(!$isPunctuationItem && $item->start_time > $duration) { |
|
$blockNumber++; |
|
$duration = $item->end_time + self::BLOCK_DURATION; |
|
} |
|
|
|
$isNewBlock =!isset($blocks[$blockNumber]); |
|
if($isNewBlock && !$isPunctuationItem){ |
|
$this->initializeBlock($blocks, $blockNumber, $item); |
|
} |
|
|
|
$isPunctuationItem ? $this->updateSentence($blocks, $blockNumber, $item) : |
|
$this->updateBlock($blocks, $blockNumber, $item); |
|
} |
|
|
|
return $this->saveCaptionFileFromBlocks($captionRequest, $blocks); |
|
} |
|
|
|
|
|
/** |
|
* @param $blocks |
|
* @param $key |
|
* @param $item |
|
*/ |
|
private function initializeBlock(&$blocks, $key, $item) { |
|
$blocks[$key] = [ |
|
'start_time' => [ |
|
'seconds' => gmdate("H:i:s", $item->start_time), |
|
'milliseconds' => explode('.', $item->start_time)[1], |
|
], |
|
'end_time' => [ |
|
'seconds' => gmdate("H:i:s", $item->end_time), |
|
'milliseconds' => explode('.', $item->end_time)[1], |
|
], |
|
'sentence' => '', |
|
]; |
|
} |
|
|
|
/** |
|
* @param $item |
|
* @return boolean |
|
*/ |
|
private function isPunctuationItem($item){ |
|
return $item->type == self::ITEM_TYPE_PUNCTUATION; |
|
} |
|
|
|
/** |
|
* @param $blocks |
|
* @param $key |
|
* @param $item |
|
*/ |
|
private function updateSentence(&$blocks, $key, $item) { |
|
$sentence = $blocks[$key]['sentence']; |
|
#Removes whitespace from the end of the last word if the current word is punctuation |
|
$this->isPunctuationItem($item) ? $sentence = substr($sentence, 0, -1) : null; |
|
$blocks[$key]['sentence'] = $sentence.$item->alternatives[0]->content." "; |
|
} |
|
|
|
/** |
|
* @param $blocks |
|
* @param $key |
|
* @param $item |
|
*/ |
|
private function updateBlock(&$blocks, $key, $item) { |
|
$this->updateSentence($blocks, $key, $item); |
|
$blocks[$key]['end_time'] = [ |
|
'seconds' => gmdate("H:i:s", $item->end_time), |
|
'milliseconds' => explode('.', $item->end_time)[1], |
|
]; |
|
} |
|
|
|
/** |
|
* @param CaptionRequest $captionRequest |
|
* @param $blocks |
|
* @return mixed |
|
* @throws Exception |
|
*/ |
|
private function saveCaptionFileFromBlocks(CaptionRequest $captionRequest, $blocks){ |
|
|
|
foreach($blocks as $key => $block){ |
|
$start = $block['start_time']['seconds'].'.'.str_pad($block['start_time']['milliseconds'], 3, "0", STR_PAD_RIGHT); |
|
$stop = $block['end_time']['seconds'].'.'.str_pad($block['end_time']['milliseconds'], 3, "0", STR_PAD_RIGHT); |
|
$this->webvttFile->addCue($block['sentence'], $start, $stop); |
|
} |
|
|
|
$this->webvttFile->build(); |
|
$this->webvttFile->save($captionRequest->localStoragePath); |
|
|
|
return $captionRequest->localStoragePath; |
|
} |
|
} |