Skip to content

Commit

Permalink
Add support for FetchVideoSource in video overlays
Browse files Browse the repository at this point in the history
  • Loading branch information
const-cloudinary committed Sep 18, 2023
1 parent e3ca9f4 commit 830b619
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 20 deletions.
22 changes: 21 additions & 1 deletion src/Transformation/Layer/BaseSourceQualifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ class BaseSourceQualifier extends BaseQualifier
*/
protected $sourceType;

/**
* @var string $assetType The type of the asset.
*/
protected $assetType;

/**
* @var string The stack position of the layer.
*/
Expand Down Expand Up @@ -75,6 +80,20 @@ public function setStackPosition($stackPosition)
return $this;
}

/**
* Sets the asset type.
*
* @param string $assetType The type of the asset.
*
* @return $this
*/
public function assetType($assetType)
{
$this->assetType = $assetType;

return $this;
}

/**
* Serializes to string.
*
Expand All @@ -83,7 +102,8 @@ public function setStackPosition($stackPosition)
public function __toString()
{
$sourceTypeStr = $this->sourceType ? "$this->sourceType:" : '';
$assetTypeStr = $this->assetType && $this->assetType != "image" ? "$this->assetType:" : '';

return empty((string)$this->value) ? '' : "{$this->getSourceKey()}_{$sourceTypeStr}{$this->value}";
return empty((string)$this->value) ? '' : "{$this->getSourceKey()}_$assetTypeStr$sourceTypeStr$this->value";
}
}
8 changes: 2 additions & 6 deletions src/Transformation/Layer/FetchImageSource.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@

namespace Cloudinary\Transformation;

use Cloudinary\Asset\AssetDescriptor;
use Cloudinary\Asset\BaseAsset;
use Cloudinary\ClassUtils;

/**
* Defines how to manipulate an image layer.
*
Expand All @@ -36,12 +32,12 @@ public function setSource($source)
{

if ($source instanceof BaseSourceQualifier) {
$this->getSourceQualifier()->setQualifierValue($source->getValue());
$this->getSourceQualifier()->fetchUrl($source->getValue());

return $this;
}

$this->getSourceQualifier()->setQualifierValue((string)$source);
$this->getSourceQualifier()->fetchUrl((string)$source);


return $this;
Expand Down
4 changes: 4 additions & 0 deletions src/Transformation/Layer/FetchSourceQualifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ public function __construct($fetchUrl)
*/
public function fetchUrl($fetchUrl)
{
if (StringUtils::contains($fetchUrl, ':fetch:')) {
list($this->assetType, $this->sourceType, $fetchUrl) = explode(':', $fetchUrl, 3);
}

$this->setQualifierValue(StringUtils::truncatePrefix($fetchUrl, 'fetch:'));

return $this;
Expand Down
74 changes: 74 additions & 0 deletions src/Transformation/Layer/FetchVideoSource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php
/**
* This file is part of the Cloudinary PHP package.
*
* (c) Cloudinary
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Cloudinary\Transformation;

use Cloudinary\ClassUtils;

/**
* Defines how to manipulate a fetched video layer.
*
* **Learn more**: <a
* href=https://cloudinary.com/documentation/video_layers#layer_transformations target="_blank">
* Video overlays</a>
*
* @api
*/
class FetchVideoSource extends VideoSource
{
/**
* VideoLayer constructor.
*
* @param $source
*/
public function __construct($source)
{
parent::__construct($source);

$this->setSource($source);
}
/**
* Sets the source of the layer.
*
* @param string|FetchSourceQualifier $source The source.
*
* @return $this
*/
public function setSource($source)
{

if ($source instanceof FetchSourceQualifier) {
$this->getSourceQualifier()->fetchUrl($source->getValue());

return $this;
}

$this->getSourceQualifier()->fetchUrl((string)$source);


return $this;
}

/**
* Gets the layer qualifier.
*
* @return FetchSourceQualifier
*
* @internal
*/
protected function getSourceQualifier()
{
if (! isset($this->qualifiers['source'])) {
$this->qualifiers['source'] = (new FetchSourceQualifier(null))->assetType("video");
}

return $this->qualifiers['source'];
}
}
15 changes: 8 additions & 7 deletions src/Transformation/Layer/LayerQualifierFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,12 @@ protected static function handleQualifierValue($layerQualifiers)
// Handle layer params
if (is_array($layerQualifiers)) {
$resourceType = ArrayUtils::get($layerQualifiers, 'resource_type');
$deliveryType = ArrayUtils::get($layerQualifiers, 'type');

// Fetch layer
$fetch = ArrayUtils::get($layerQualifiers, 'fetch');
if (! empty($fetch) || $resourceType === 'fetch') {
return new FetchSourceQualifier($fetch);
$fetchUrl = ArrayUtils::get($layerQualifiers, 'fetch', ArrayUtils::get($layerQualifiers, 'url'));
if (! empty($fetchUrl) || $deliveryType === 'fetch') {
return (new FetchSourceQualifier($fetchUrl))->assetType($resourceType);
}

$text = ArrayUtils::get($layerQualifiers, 'text');
Expand Down Expand Up @@ -100,17 +101,17 @@ protected static function handleQualifierValue($layerQualifiers)
if ($resourceType !== 'image') {
$components[] = $resourceType;
}
$type = ArrayUtils::get($layerQualifiers, 'type');
if ($type !== 'upload') {
$components[] = $type;

if ($deliveryType !== 'upload') {
$components[] = $deliveryType;
}
$components[] = $publicId;

// Build a valid layer string.
$layerQualifiers = ArrayUtils::implodeQualifierValues(...$components);
} elseif (is_string($layerQualifiers)) {
// Handle fetch layer from string definition.
if (StringUtils::startsWith($layerQualifiers, 'fetch:')) {
if (StringUtils::contains($layerQualifiers, 'fetch:')) {
return new FetchSourceQualifier($layerQualifiers);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Transformation/Layer/VideoSourceQualifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
class VideoSourceQualifier extends BaseSourceQualifier
{
/**
* @var string $sourceType The type of the layer.
* @var string $assetType The asset type of the layer.
*/
protected $sourceType = 'video';
protected $assetType = 'video';

/**
* VideoSourceQualifier constructor.
Expand Down
12 changes: 12 additions & 0 deletions src/Transformation/Layer/VideoSourceTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@ public static function video($videoId = null)
return static::createWithSource(ClassUtils::verifyInstance($videoId, VideoSource::class));
}

/**
* Adds another video layer from a remote URL.
*
* @param string|null $fetchUrl The URL of the asset to fetch.
*
* @return static|FetchVideoSource
*/
public static function fetchVideo($fetchUrl)
{
return static::createWithSource(ClassUtils::verifyInstance($fetchUrl, FetchVideoSource::class));
}

/**
* Adds subtitles to a video.
*
Expand Down
8 changes: 7 additions & 1 deletion tests/TransformationTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,21 @@
*/
abstract class TransformationTestCase extends TestCase
{
const ASSET_ID = 'sample';
const ASSET_ID = 'sample';
const VIDEO_ASSET_ID = 'dog';

const IMG_EXT = 'png';
const IMG_EXT_JPG = 'jpg';
const IMG_EXT_GIF = 'gif';
const IMAGE_NAME = self::ASSET_ID . '.' . self::IMG_EXT;
const IMAGE_NAME_GIF = self::ASSET_ID . '.' . self::IMG_EXT_GIF;

const VIDEO_EXT = 'mp4';
const VIDEO_NAME = self::VIDEO_ASSET_ID . '.' . self::VIDEO_EXT;
const FETCH_IMAGE_URL = 'https://res.cloudinary.com/demo/image/upload/' . self::IMAGE_NAME;
const FETCH_VIDEO_URL = 'https://res.cloudinary.com/demo/video/upload/' . self::VIDEO_NAME;

const B64_FETCH_VIDEO_URL = 'aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vZGVtby92aWRlby91cGxvYWQvZG9nLm1wNA==';

/**
* Asserts that string representations of the objects are equal.
Expand Down
8 changes: 8 additions & 0 deletions tests/Unit/Transformation/Common/ActionFromQualifiersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,10 @@ public function layersQualifiersDataProvider()
'private' => [['public_id' => 'logo', 'type' => 'private'], 'private:logo'],
'format' => [['public_id' => 'logo', 'format' => 'png'], 'logo.png'],
'video' => [['resource_type' => 'video', 'public_id' => 'cat'], 'video:cat'],
'fetch video' => [
['resource_type' => 'video', 'url' => self::FETCH_VIDEO_URL],
'video:fetch:' . self::B64_FETCH_VIDEO_URL
],
'text' => [
['public_id' => 'logo', 'text' => 'Hello World, Nice to meet you?'],
'text:logo:Hello%20World%252C%20Nice%20to%20meet%20you%3F',
Expand Down Expand Up @@ -722,6 +726,10 @@ public function layersQualifiersDataProvider()
'fetch:' . self::FETCH_IMAGE_URL,
'fetch:aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vZGVtby9pbWFnZS91cGxvYWQvc2FtcGxlLnBuZw==',
],
'fetch video url' => [
'video:fetch:' . self::FETCH_VIDEO_URL,
'video:fetch:' . self::B64_FETCH_VIDEO_URL,
],
'logo' => [
['public_id' => 'logo', 'type' => 'upload', 'resource_type' => 'image'],
'logo',
Expand Down
14 changes: 11 additions & 3 deletions tests/Unit/Transformation/Video/VideoOverlayTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace Cloudinary\Test\Unit\Transformation\Video;

use Cloudinary\Transformation\AudioSource;
use Cloudinary\Test\TransformationTestCase;
use Cloudinary\Transformation\Compass;
use Cloudinary\Transformation\CompassPosition;
use Cloudinary\Transformation\Concatenate;
Expand All @@ -25,12 +25,11 @@
use Cloudinary\Transformation\VideoOverlay;
use Cloudinary\Transformation\VideoSource;
use Cloudinary\Transformation\VideoTransformation;
use PHPUnit\Framework\TestCase;

/**
* Class VideoOverlayTest
*/
final class VideoOverlayTest extends TestCase
final class VideoOverlayTest extends TransformationTestCase
{
public function testVideoOverlay()
{
Expand Down Expand Up @@ -109,6 +108,15 @@ public function testVideoCutter()
);
}

public function testVideoFetch()
{
self::assertEquals(
"l_video:fetch:" . self::B64_FETCH_VIDEO_URL . "/fl_layer_apply",
(string)(new VideoTransformation())
->overlay(Overlay::videoSource(VideoSource::fetchVideo(self::FETCH_VIDEO_URL)))
);
}

public function testAudioOverlay()
{
self::assertEquals(
Expand Down

0 comments on commit 830b619

Please sign in to comment.