Files
server/usr/share/psa-horde/imp/lib/Mime/Viewer/Video.php
2026-01-07 20:52:11 +01:00

191 lines
5.3 KiB
PHP

<?php
/**
* Copyright 2011-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (GPL). If you
* did not receive this file, see http://www.horde.org/licenses/gpl.
*
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/gpl GPL
* @package IMP
*/
/**
* Renderer to output information on:
* 1. The duration of the video data, if that information was provided in
* the original message.
* 2. Output thumbnails of the video file.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2011-2017 Horde LLC
* @license http://www.horde.org/licenses/gpl GPL
* @package IMP
*/
class IMP_Mime_Viewer_Video extends Horde_Mime_Viewer_Default
{
/**
* This driver's display capabilities.
*
* @var array
*/
protected $_capability = array(
'full' => false,
'info' => true,
'inline' => true,
'raw' => false
);
/**
* Return the full rendered version of the Horde_Mime_Part object.
*
* URL parameters used by this function:
* - imp_video_view: (string) One of the following:
* - view_thumbnail: Create thumbnail and display.
*
* @return array See parent::render().
*/
protected function _render()
{
switch ($GLOBALS['injector']->getInstance('Horde_Variables')->imp_video_view) {
case 'view_thumbnail':
/* Create thumbnail and display. */
return $this->_thumbnail();
default:
return parent::_render();
}
}
/**
* Return the rendered information about the Horde_Mime_Part object.
*
* @return array See parent::render().
*/
protected function _renderInfo()
{
global $registry;
if ($registry->getView() == $registry::VIEW_MINIMAL) {
return array();
}
$status = array();
$mime_id = $this->_mimepart->getMimeId();
$headers = Horde_Mime_Headers::parseHeaders($this->getConfigParam('imp_contents')->getBodyPart($mime_id, array(
'length' => 0,
'mimeheaders' => true,
'stream' => true
))->data);
if (($duration = $headers->getValue('content-duration')) !== null) {
$text = array();
if ($minutes = floor($duration / 60)) {
$text[] = sprintf(
ngettext(_("%d minute"), _("%d minutes"), $minutes),
$minutes
);
}
if ($seconds = ($duration % 60)) {
$text[] = sprintf(
ngettext(_("%d second"), _("%d seconds"), $seconds),
$seconds
);
}
$status[] = sprintf(_("This video file is reported to be %s in length."), implode(' ', $text));
}
if ($this->_thumbnailBinary()) {
$status[] = _("This is a thumbnail of a video attachment.");
$status[] = $this->getConfigParam('imp_contents')->linkViewJS(
$this->_mimepart,
'view_attach',
'<img src="' . $this->getConfigParam('imp_contents')->urlView($this->_mimepart, 'view_attach', array('params' => array('imp_video_view' => 'view_thumbnail'))) . '" />',
null,
null,
null
);
}
if (empty($status)) {
return array();
}
$s = new IMP_Mime_Status($status);
$s->icon('mime/video.png');
return array(
$this->_mimepart->getMimeId() => array(
'data' => '',
'status' => $s,
'type' => 'text/html; charset=UTF-8'
)
);
}
/**
* Generate thumbnail for the video.
*
* @return array See parent::render().
*/
protected function _thumbnail()
{
if (!($ffmpeg = $this->_thumbnailBinary())) {
return array();
}
$process = proc_open(
escapeshellcmd($ffmpeg) . ' -i pipe:0 -vframes 1 -an -ss 1 -s 240x180 -f mjpeg pipe:1',
array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w')
),
$pipes
);
$out = null;
if (is_resource($process)) {
fwrite($pipes[0], $this->_mimepart->getContents());
fclose($pipes[0]);
$out = stream_get_contents($pipes[1]);
fclose($pipes[1]);
}
if (strlen($out)) {
$type = 'image/jpeg';
} else {
$type = 'image/png';
$img_ob = Horde_Themes::img('mini-error.png', 'imp');
$out = file_get_contents($img_ob->fs);
}
return array(
$this->_mimepart->getMimeId() => array(
'data' => $out,
'type' => 'image/jpeg'
)
);
}
/**
* Get the ffmpeg binary.
*
* @return mixed The binary location, or false if not available.
*/
protected function _thumbnailBinary()
{
return ($this->getConfigParam('thumbnails') &&
($ffmpeg = $this->getConfigParam('ffmpeg')) &&
is_executable($ffmpeg))
? $ffmpeg
: false;
}
}