Skip to content
Next
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Switch to GitLab Next
Sign in / Register
Toggle navigation
Minds Backend - Engine
Project
Project
Details
Activity
Releases
Dependency List
Cycle Analytics
Insights
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Locked Files
Issues
150
Issues
150
List
Boards
Labels
Service Desk
Milestones
Merge Requests
48
Merge Requests
48
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Minds
Minds Backend - Engine
Compare Revisions
4ba9bcbd0aed4ead3dbd72eef2c16790243fe044...b9a83297ee511dc33ba7fc39f817fe29ee514ebe
Source
b9a83297ee511dc33ba7fc39f817fe29ee514ebe
Select Git revision
...
Target
4ba9bcbd0aed4ead3dbd72eef2c16790243fe044
Select Git revision
Compare
Commits (2)
(feat): Client uploader
· ecf4c2df
Mark Harding
authored
13 minutes ago
ecf4c2df
Merge branch 'feat/client-uploader' into 'master'
· b9a83297
Mark Harding
authored
13 minutes ago
(feat): Client uploader See merge request
!263
b9a83297
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
364 additions
and
0 deletions
+364
-0
upload.php
Controllers/api/v2/media/upload.php
+76
-0
ClientUploadLease.php
Core/Media/ClientUpload/ClientUploadLease.php
+42
-0
Manager.php
Core/Media/ClientUpload/Manager.php
+88
-0
MediaProvider.php
Core/Media/MediaProvider.php
+12
-0
FFMpeg.php
Core/Media/Services/FFMpeg.php
+14
-0
ManagerSpec.php
Spec/Core/Media/ClientUpload/ManagerSpec.php
+81
-0
FFMpegSpec.php
Spec/Core/Media/Services/FFMpegSpec.php
+51
-0
No files found.
Controllers/api/v2/media/upload.php
0 → 100644
View file @
b9a83297
<?php
/**
* Client based upload
*
* @author Mark Harding
*/
namespace
Minds\Controllers\api\v2\media
;
use
Minds\Api\Factory
;
use
Minds\Core\Di\Di
;
use
Minds\Interfaces
;
use
Minds\Core\Media\ClientUpload\ClientUploadLease
;
class
upload
implements
Interfaces\Api
{
/**
* Equivalent to HTTP GET method
* @param array $pages
* @return mixed|null
*/
public
function
get
(
$pages
)
{
return
Factory
::
response
([]);
}
public
function
post
(
$pages
)
{
return
Factory
::
response
([]);
}
/**
* Equivalent to HTTP PUT method
* @param array $pages
* @return mixed|null
*/
public
function
put
(
$pages
)
{
$manager
=
Di
::
_
()
->
get
(
"Media\ClientUpload\Manager"
);
switch
(
$pages
[
0
])
{
case
'prepare'
:
$mediaType
=
$pages
[
1
]
??
'not-set'
;
$lease
=
$manager
->
prepare
(
$mediaType
);
return
Factory
::
response
([
'lease'
=>
$lease
->
export
(),
]);
break
;
case
'complete'
:
$mediaType
=
$pages
[
1
]
??
'not-set'
;
$guid
=
$pages
[
2
]
??
null
;
$lease
=
new
ClientUploadLease
();
$lease
->
setGuid
(
$guid
)
->
setMediaType
(
$mediaType
);
$manager
->
complete
(
$lease
);
break
;
}
return
Factory
::
response
([]);
}
/**
* Equivalent to HTTP DELETE method
* @param array $pages
* @return mixed|null
*/
public
function
delete
(
$pages
)
{
return
Factory
::
response
([]);
}
}
This diff is collapsed.
Click to expand it.
Core/Media/ClientUpload/ClientUploadLease.php
0 → 100644
View file @
b9a83297
<?php
namespace
Minds\Core\Media\ClientUpload
;
use
Minds\Traits\MagicAttributes
;
/**
* Class ClientUploadLease
* @package Minds\Core\Media\ClientUpload
* @method string getGuid()
* @method string getMediaType()
* @method string getPresignedUrl()
*/
class
ClientUploadLease
{
use
MagicAttributes
;
/** @var string $guid */
private
$guid
;
/** @var string $presignedUrl */
private
$presignedUrl
;
/** @var string $mediaType */
private
$mediaType
;
/**
* Export to API
* @param array $extra
* @return array
*/
public
function
export
(
$extra
=
[])
{
return
[
'guid'
=>
(
string
)
$this
->
getGuid
(),
'presigned_url'
=>
$this
->
getPresignedUrl
(),
'media_type'
=>
$this
->
getMediaType
(),
];
}
}
This diff is collapsed.
Click to expand it.
Core/Media/ClientUpload/Manager.php
0 → 100644
View file @
b9a83297
<?php
/**
* Client Upload, direct from browser to storage
*/
namespace
Minds\Core\Media\ClientUpload
;
use
Minds\Core\Media\Services\FFMpeg
;
use
Minds\Core\GuidBuilder
;
use
Minds\Core\Entities\Actions\Save
;
use
Minds\Core\Di\Di
;
use
Minds\Entities\Video
;
class
Manager
{
/** @var FFMepg */
private
$ffmpeg
;
/** @var Guid $guid */
private
$guid
;
/** @var Save $save */
private
$save
;
public
function
__construct
(
FFMpeg
$FFMpeg
=
null
,
GuidBuilder
$guid
=
null
,
Save
$save
=
null
)
{
$this
->
ffmpeg
=
$FFMpeg
?:
Di
::
_
()
->
get
(
'Media\Services\FFMpeg'
);
$this
->
guid
=
$guid
?:
new
GuidBuilder
();
$this
->
save
=
$save
?:
new
Save
();
}
/**
* Prepare an upload, return a lease
* @param $type - the media type
* @return ClientUploadLease
*/
public
function
prepare
(
$type
=
'video'
)
{
if
(
$type
!=
'video'
)
{
throw
new
\Exception
(
"
$type
is not currently supported for client based uploads"
);
}
$guid
=
$this
->
guid
->
build
();
$this
->
ffmpeg
->
setKey
(
$guid
);
$preSignedUrl
=
$this
->
ffmpeg
->
getPresignedUrl
();
$lease
=
new
ClientUploadLease
();
$lease
->
setGuid
(
$guid
)
->
setMediaType
(
$type
)
->
setPresignedUrl
(
$preSignedUrl
);
return
$lease
;
}
/**
* Complete the client based upload
* @param ClientUploadLease $lease
* @return boolean
*/
public
function
complete
(
ClientUploadLease
$lease
)
{
if
(
$lease
->
getMediaType
()
!==
'video'
)
{
throw
new
\Exception
(
"
{
$lease
->
getMediaType
()
}
is not currently supported for client based uploads"
);
}
$video
=
new
Video
();
$video
->
set
(
'guid'
,
$lease
->
getGuid
());
$video
->
set
(
'cinemr_guid'
,
$lease
->
getGuid
());
$video
->
set
(
'access_id'
,
0
);
// Hide until published
// Save the video
$this
->
save
->
setEntity
(
$video
)
->
save
();
$this
->
ffmpeg
->
setKey
(
$lease
->
getGuid
());
// Start the transcoding process
$this
->
ffmpeg
->
transcode
();
return
true
;
}
}
This diff is collapsed.
Click to expand it.
Core/Media/MediaProvider.php
View file @
b9a83297
...
...
@@ -59,5 +59,17 @@ class MediaProvider extends Provider
$this
->
di
->
bind
(
'Media\Imagick\Manager'
,
function
(
$di
)
{
return
new
Imagick\Manager
();
},
[
'useFactory'
=>
false
]);
// ClientUpload
$this
->
di
->
bind
(
'Media\ClientUpload\Manager'
,
function
(
$di
)
{
return
new
ClientUpload\Manager
();
},
[
'useFactory'
=>
true
]);
// Services
$this
->
di
->
bind
(
'Media\Services\FFMpeg'
,
function
(
$di
)
{
return
new
Services\FFMpeg
();
},
[
'useFactory'
=>
false
]);
}
}
This diff is collapsed.
Click to expand it.
Core/Media/Services/FFMpeg.php
View file @
b9a83297
...
...
@@ -78,6 +78,20 @@ class FFMpeg implements ServiceInterface
return
$this
;
}
/**
* Create a PresignedUr for client based uploads
* @return string
*/
public
function
getPresignedUrl
()
{
$cmd
=
$this
->
s3
->
getCommand
(
'PutObject'
,
[
'Bucket'
=>
'cinemr'
,
'Key'
=>
"
$this->dir
/
$this->key
/source"
,
]);
return
(
string
)
$this
->
s3
->
createPresignedRequest
(
$cmd
,
'+20 minutes'
)
->
getUri
();
}
public
function
saveToFilestore
(
$file
)
{
try
{
...
...
This diff is collapsed.
Click to expand it.
Spec/Core/Media/ClientUpload/ManagerSpec.php
0 → 100644
View file @
b9a83297
<?php
namespace
Spec\Minds\Core\Media\ClientUpload
;
use
Minds\Core\Media\ClientUpload\Manager
;
use
Minds\Core\Media\ClientUpload\ClientUploadLease
;
use
Minds\Core\Media\Services\FFMpeg
;
use
Minds\Core\GuidBuilder
;
use
Minds\Core\Entities\Actions\Save
;
use
PhpSpec\ObjectBehavior
;
use
Prophecy\Argument
;
class
ManagerSpec
extends
ObjectBehavior
{
private
$ffmpeg
;
private
$guid
;
private
$save
;
function
let
(
FFMpeg
$FFMpeg
,
GuidBuilder
$guid
,
Save
$save
)
{
$this
->
beConstructedWith
(
$FFMpeg
,
$guid
,
$save
);
$this
->
ffmpeg
=
$FFMpeg
;
$this
->
guid
=
$guid
;
$this
->
save
=
$save
;
}
function
it_is_initializable
()
{
$this
->
shouldHaveType
(
Manager
::
class
);
}
function
it_should_return_an_upload_lease
()
{
$this
->
guid
->
build
()
->
willReturn
(
123
);
$this
->
ffmpeg
->
setKey
(
123
)
->
shouldBeCalled
();
$this
->
ffmpeg
->
getPresignedUrl
()
->
willReturn
(
's3-url-here'
);
$lease
=
$this
->
prepare
(
'video'
);
$lease
->
getMediaType
()
->
shouldBe
(
'video'
);
$lease
->
getGuid
()
->
shouldBe
(
123
);
$lease
->
getPresignedUrl
()
->
shouldBe
(
's3-url-here'
);
}
function
it_should_complete_an_upload
(
ClientUploadLease
$lease
)
{
$lease
->
getMediaType
()
->
willReturn
(
'video'
);
$lease
->
getGuid
()
->
willReturn
(
456
);
$this
->
save
->
setEntity
(
Argument
::
that
(
function
(
$video
)
{
return
$video
->
guid
==
456
&&
$video
->
access_id
==
0
;
}))
->
shouldBeCalled
()
->
willReturn
(
$this
->
save
);
$this
->
save
->
save
()
->
shouldBeCalled
();
$this
->
ffmpeg
->
setKey
(
456
)
->
shouldBeCalled
();
$this
->
ffmpeg
->
transcode
()
->
shouldBeCalled
();
$this
->
complete
(
$lease
)
->
shouldReturn
(
true
);
}
}
This diff is collapsed.
Click to expand it.
Spec/Core/Media/Services/FFMpegSpec.php
0 → 100644
View file @
b9a83297
<?php
namespace
Spec\Minds\Core\Media\Services
;
use
Minds\Core\Media\Services\FFMpeg
;
use
FFMpeg\FFMpeg
as
FFMpegClient
;
use
FFMpeg\FFProbe
as
FFProbeClient
;
use
Minds\Core\Queue\Interfaces\QueueClient
;
use
Psr\Http\Message\RequestInterface
;
use
Aws\S3\S3Client
;
use
PhpSpec\ObjectBehavior
;
use
Prophecy\Argument
;
class
FFMpegSpec
extends
ObjectBehavior
{
function
it_is_initializable
()
{
$this
->
shouldHaveType
(
FFMpeg
::
class
);
}
function
it_should_get_a_presigned_urn
(
QueueClient
$queue
,
FFMpegClient
$ffmpeg
,
FFProbeClient
$ffprobe
,
S3Client
$s3
,
\Aws\CommandInterface
$cmd
,
RequestInterface
$request
)
{
$this
->
beConstructedWith
(
$queue
,
$ffmpeg
,
$ffprobe
,
$s3
);
$s3
->
getCommand
(
'PutObject'
,
[
'Bucket'
=>
'cinemr'
,
'Key'
=>
"/123/source"
,
])
->
shouldBeCalled
()
->
willReturn
(
$cmd
);
$s3
->
createPresignedRequest
(
Argument
::
any
(),
Argument
::
any
())
->
willReturn
(
$request
);
$request
->
getUri
()
->
willReturn
(
'aws-signed-url'
);
$this
->
setKey
(
123
);
$this
->
getPresignedUrl
()
->
shouldReturn
(
'aws-signed-url'
);
}
}
This diff is collapsed.
Click to expand it.