-
-
Save ayozehd/f8dab66db80c0122475fed80115a1a02 to your computer and use it in GitHub Desktop.
Video previews Transloadit Sample (Symfony, Twig, Javascript)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace AppBundle\Controller; | |
use App\Entity; | |
use Symfony\Bundle\FrameworkBundle\Controller\Controller; | |
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | |
use Symfony\Component\HttpFoundation\Request; | |
use Symfony\Component\HttpFoundation\JsonResponse; | |
use transloadit\Transloadit; | |
use Exception; | |
class AssemblyController extends Controller | |
{ | |
protected $em; | |
protected $logger; | |
/** | |
* @Route("/assembly/answer", name="assemblyAnswerVideo", methods={"POST"}) | |
*/ | |
public function assemblyAnswerVideoAction(Request $request) | |
{ | |
$this->initialize(); | |
$answer_id = $request->query->get('answer_id'); | |
$answer = $this->em | |
->getRepository('App:Answer') | |
->find($answer_id); | |
if($answer instanceof Entity\Answer) { | |
$response = Transloadit::response(); | |
if (!$response->error()) { | |
$results = $response->data['results']; | |
foreach($results as $step => $result) { | |
switch($step) { | |
case 'watermarked': | |
$answer->setVideoMp4($result[0]['ssl_url']); | |
break; | |
case 'webm_encode': | |
$answer->setVideoWebm($result[0]['ssl_url']); | |
break; | |
case 'ogv_encode': | |
$answer->setVideoOgv($result[0]['ssl_url']); | |
break; | |
case 'thumbailed': | |
$answer->setVideoThumbnail($result[0]['ssl_url']); | |
break; | |
default: | |
} | |
} | |
$answer->setVideoProcess(false); | |
$this->em->flush(); | |
$question = $answer->getParent(); | |
$user = $question->getUser(); | |
$locale = $user->getLocale(); | |
$this->get('app.mailer') | |
->new( | |
$user->getEmail(), | |
$this->get('translator')->trans('question.answered', [], 'messages', $locale), | |
'email/answered-question.html.twig', | |
[ | |
'url' => $this->generateUrl('answer', array('username' => $user->getUsername(), 'hash' => $enquiry->getHash()), true), | |
'locale' => $locale | |
] | |
); | |
$this->logger->info('[Assembly Notification] We received an assembly notification succesfully', [ | |
'answer_id' => $answer_id | |
]); | |
return $this->response(); | |
} else { | |
$this->logger->error('[Assembly Notification] Transloadit returned an error response', [ | |
'answer_id' => $answer_id, | |
'error_msg' => $response | |
]); | |
} | |
} else { | |
$this->logger->critical('[Assembly Notification] We cannot find the answer ID for a Transload Assembly Notification. Check database integrity.', [ | |
'answer_id' => $answer_id | |
]); | |
} | |
return $this->response(false); | |
} | |
// ... | |
protected function response($success = true) | |
{ | |
$response = new JsonResponse( | |
array( | |
'success' => $success, | |
) | |
); | |
if(!$success) { | |
$response->setStatusCode(400); | |
} | |
return $response; | |
} | |
protected function initialize() { | |
$this->em = $this->getDoctrine()->getManager(); | |
$this->logger = $this->get('monolog.logger.transload'); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% extends "base.html.twig" %} | |
{% block content %} | |
<form method="post" action="{{ path('messageReplySubmit', {id: message.id}) }}"> | |
... | |
</form> | |
{% endblock %} | |
{% block javascript %} | |
{{ parent() }} | |
<script src="{{ asset('/js/uppy.min.js') }}"></script> | |
<script type="text/javascript"> | |
const supportedBrowserVideoFormats = [ | |
'video/mp4', | |
'video/webm', | |
'video/ogg' | |
]; | |
var uppy = buildUppyWidget(); | |
uppy.on('upload', (data) => { | |
disableFormSubmission(); | |
}); | |
uppy.on('transloadit:complete', (assembly) => { | |
if(assembly.ok != 'error') { | |
var upload, preview, poster = null; | |
for(var i in assembly.uploads) { | |
upload = assembly.uploads[i].ssl_url; | |
} | |
if('mp4_encode' in assembly.results) { | |
for(var i in assembly.results.mp4_encode) { | |
preview = assembly.results.mp4_encode[i].ssl_url; | |
} | |
} | |
if('thumbailed' in assembly.results) { | |
for(var i in assembly.results.thumbailed) { | |
poster = assembly.results.thumbailed[i].ssl_url || assembly.results.thumbailed[i].url; | |
} | |
} | |
videoThumbnail(upload, preview, poster); | |
$('#removeFile').on('click touch', function(e) { | |
e.preventDefault(); | |
restoreVideoUpload(); | |
}); | |
} | |
disableFormSubmission(true); | |
}); | |
function buildUppyWidget() | |
{ | |
return Uppy.Core({ | |
debug: false, | |
autoProceed: true, | |
no_cors: true, | |
allowMultipleUploads: false, | |
restrictions: { | |
maxFileSize: 1024 * 1024 * 500, // Max 500MB | |
maxNumberOfFiles: 1, | |
minNumberOfFiles: 1, | |
allowedFileTypes: ['video/*'], | |
} | |
}) | |
.use(Uppy.Transloadit, { | |
params: { | |
auth: { | |
// To avoid tampering use signatures: | |
// https://transloadit.com/docs/api/#authentication | |
key: '{{ transload_key }}' | |
}, | |
template_id: '{{ transload_assembly_upload_temp }}' | |
}, | |
waitForEncoding: true | |
}) | |
.use(Uppy.FileInput, { | |
target: '#video-upload', | |
pretty: true | |
}) | |
.use(Uppy.StatusBar, { | |
target: '#video-status', | |
hideAfterFinish: false, | |
hideCancelButton: true | |
}) | |
.use(Uppy.Informer, { | |
target: 'body', | |
replaceTargetContent: false | |
}); | |
} | |
function videoThumbnail(original, preview, poster) { | |
var div = $('.reply-thumbnail-video'); | |
var thumbnail = ` | |
<div class="thumbnail"> | |
`+ addVideoData(original) + ` | |
<video controls="1" ` + (poster ? 'poster="' + poster + '"' : null) + `> | |
<source src="${preview}" type="video/mp4"></video> | |
</div> | |
` + videoRemoveButton(); | |
div.append(thumbnail); | |
} | |
function addVideoData(url) { | |
return ` | |
<input type="hidden" name="video_url" value="${url}"> | |
`; | |
} | |
function restoreVideoUpload() { | |
var div = $('.reply-thumbnail-video'); | |
div.empty(); | |
uppy.reset(); | |
disableFormSubmission(true); | |
} | |
function videoRemoveButton() { | |
return `<button class="btn btn-danger btn-block" id="removeFile">Remove</button>`; | |
} | |
function disableFormSubmission(status) | |
{ | |
if(!status) { | |
status = false; | |
} | |
$('form button[type="submit"]').prop('disabled', !status); | |
} | |
</script> | |
{% endblock %} | |
{% block stylesheets %} | |
{{ parent() }} | |
<link href="{{ asset('/css/uppy.min.css') }}" rel="stylesheet"> | |
<link href="{{ asset('/css/custom-uppy.min.css') }}" rel="stylesheet"> | |
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Controller; | |
use Symfony\Component\HttpFoundation\RedirectResponse; | |
use Symfony\Component\HttpFoundation\Request; | |
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | |
use App\Entity; | |
use transloadit\Transloadit; | |
class ReplyController extends BaseController | |
{ | |
/** | |
* @Route("/message/reply/{id}", name="messageReply", requirements={"id"="\d+"}) | |
*/ | |
public function messageReplyAction(Request $request, $id) | |
{ | |
$this->initialize($request); | |
$user = $this->getUser(); | |
$msg = $this->getDoctrine() | |
->getRepository('App:Message') | |
->find($id); | |
if(!$msg){ | |
$this->addFlash('error', $this->get('translator')->trans('error.message.missing')); | |
return $this->redirectToRoute('messages'); | |
} | |
return $this->render('reply.html.twig', [ | |
'user' => $user, | |
'message' => $msg | |
]); | |
} | |
/** | |
* @Route("/message/reply/{id}/submit", name="messageReplySubmit", requirements={"id"="\d+"}) | |
*/ | |
public function messageReplySubmitAction(Request $request, $id) | |
{ | |
$user = $this->getUser(); | |
$msg = $this->getDoctrine() | |
->getRepository('App:Message') | |
->find($id); | |
if(!$msg){ | |
// TODO not found exception | |
$this->addFlash('error', $this->get('translator')->trans('error.message.missing')); | |
return $this->redirectToRoute('messages'); | |
} | |
if ($request->isMethod('POST')) { | |
$videoUrl = $request->request->get('video_url'); | |
if(!$videoUrl || $videoUrl == '') { | |
$this->addFlash('error', $this->get('translator')->trans('error.message.answer_empty')); | |
return $this->redirectToRoute('messages'); | |
} | |
$answer = new Entity\Answer(); | |
$answer->setParent($msg); | |
$answer->setUser($user); | |
$answer->setCreatedAt(new \DateTime()); | |
if($videoUrl) { | |
$answer->setVideoProcess(true); | |
} | |
$this->getDoctrine() | |
->getRepository('App:Answer') | |
->insert($answer); | |
// REQUEST TRANSCODE VIDEO ASYNC | |
if($videoUrl) { | |
/** @var $logger LoggerInterface */ | |
$logger = $this->get('monolog.logger.transload'); | |
$transloadit = new Transloadit(array( | |
'key' => $this->container->getParameter('transload_key'), | |
'secret' => $this->container->getParameter('transload_secret'), | |
)); | |
$router = $this->get('router'); | |
// Transload Assembly Notifications host on dev environment via ngrock https://ngrok.com | |
if($this->get('kernel')->isDebug()) { | |
$context = $router->getContext(); | |
$context->setHost($this->container->getParameter('transload_assembly_host')); | |
$context->setScheme('http'); | |
} | |
$notifyUrl = $router->generate('assemblyTopicAnswerVideo', [ | |
'answer_id' => $answer->getId() | |
], true); | |
try { | |
$response = $transloadit->createAssembly(array( | |
'params' => array( | |
"notify_url" => $notifyUrl, | |
'template_id' => $this->container->getParameter('transload_assembly_message'), | |
'steps' => array( | |
'imported' => array( | |
'url' => $videoUrl | |
) | |
) | |
) | |
)); | |
} catch(Exception $e) { | |
$logger->error('[Assembly Request] Something was wrong sending assembly request to Transloadit', [ | |
'template' => $this->container->getParameter('transload_assembly_thread'), | |
'answer_id' => $answer->getId(), | |
'video_url' => $videoUrl, | |
'notification_url' => $notifyUrl, | |
'error_msg' => $e->getMessage() | |
]); | |
} | |
$logger->info('[Assembly Request] Video processing request to Transloadit', [ | |
'template' => $this->container->getParameter('transload_assembly_thread'), | |
'answer_id' => $answer->getId(), | |
'video_url' => $videoUrl, | |
'notification_url' => $notifyUrl | |
]); | |
} | |
$this->addFlash('success', $this->get('translator')->trans('message.replied')); | |
} | |
return $this->redirectToRoute('messages'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment