diff --git a/inc/config.php b/inc/config.php
index 1525b8bb..3dd8eb6c 100644
--- a/inc/config.php
+++ b/inc/config.php
@@ -751,6 +751,13 @@
// Display the file's original filename.
$config['show_filename'] = true;
+ // WebM Settings
+ $config['webm']['use_ffmpeg'] = false;
+ $config['webm']['allow_audio'] = false;
+ $config['webm']['max_length'] = 120;
+ $config['webm']['ffmpeg_path'] = 'ffmpeg';
+ $config['webm']['ffprobe_path'] = 'ffprobe';
+
// Display image identification links for ImgOps, regex.info/exif, Google Images and iqdb.
$config['image_identification'] = false;
// Which of the identification links to display. Only works if $config['image_identification'] is true.
@@ -760,6 +767,9 @@
// Anime/manga search engine.
$config['image_identification_iqdb'] = false;
+ // Set this to true if you're using a BSD
+ $config['bsd_md5'] = false;
+
// Number of posts in a "View Last X Posts" page
$config['noko50_count'] = 50;
// Number of posts a thread needs before it gets a "View Last X Posts" page.
@@ -1032,6 +1042,10 @@
$config['error']['unknownext'] = _('Unknown file extension.');
$config['error']['filesize'] = _('Maximum file size: %maxsz% bytes
Your file\'s size: %filesz% bytes');
$config['error']['maxsize'] = _('The file was too big.');
+ $config['error']['webmerror'] = _('There was a problem processing your webm.');
+ $config['error']['invalidwebm'] = _('Invalid webm uploaded.');
+ $config['error']['webmhasaudio'] = _('The uploaded webm contains an audio or another type of additional stream.');
+ $config['error']['webmtoolong'] = _('The uploaded webm is longer than ' . $config['webm']['max_length'] . ' seconds.');
$config['error']['fileexists'] = _('That file already exists!');
$config['error']['fileexistsinthread'] = _('That file already exists in this thread!');
$config['error']['delete_too_soon'] = _('You\'ll have to wait another %s before deleting that.');
@@ -1039,6 +1053,7 @@
$config['error']['invalid_embed'] = _('Couldn\'t make sense of the URL of the video you tried to embed.');
$config['error']['captcha'] = _('You seem to have mistyped the verification.');
+
// Moderator errors
$config['error']['toomanyunban'] = _('You are only allowed to unban %s users at a time. You tried to unban %u users.');
$config['error']['invalid'] = _('Invalid username and/or password.');
diff --git a/inc/lib/webm/README.md b/inc/lib/webm/README.md
index baa7a641..dc3394c9 100644
--- a/inc/lib/webm/README.md
+++ b/inc/lib/webm/README.md
@@ -20,6 +20,16 @@ Add these lines to inc/instance-config.php:
$config['additional_javascript'][] = 'js/webm-settings.js';
$config['additional_javascript'][] = 'js/expand-video.js';
+If you have an [FFmpeg](https://www.ffmpeg.org/) binary on your server and you wish to generate real thumbnails (the webm thumbnails created with the original implementation reportedly cause users' browsers to crash), add the following to inc/instance-config.php as well:
+
+ $config['webm']['use_ffmpeg'] = true;
+
+ // If your ffmpeg binary isn't in your path you need to set these options
+ // as well.
+
+ $config['webm']['ffmpeg_path'] = '/path/to/ffmeg';
+ $config['webm']['ffprobe_path'] = '/path/to/ffprobe';
+
License
-------
diff --git a/inc/lib/webm/ffmpeg.php b/inc/lib/webm/ffmpeg.php
new file mode 100644
index 00000000..edd2c73a
--- /dev/null
+++ b/inc/lib/webm/ffmpeg.php
@@ -0,0 +1,62 @@
+ 1, 'msg' => $config['error']['genwebmerror']);
+
+ if ($ffprobe_out['format']['format_name'] != 'matroska,webm')
+ return array('code' => 2, 'msg' => $config['error']['invalidwebm']);
+
+ if ((count($ffprobe_out['streams']) > 1) && (!$config['webm']['allow_audio']))
+ return array('code' => 3, 'msg' => $config['error']['webmhasaudio']);
+
+ if ($ffprobe_out['streams'][0]['codec_name'] != 'vp8')
+ return array('code' => 2, 'msg' => $config['error']['invalidwebm']);
+
+ if (empty($ffprobe_out['streams'][0]['width']) || (empty($ffprobe_out['streams'][0]['height'])))
+ return array('code' => 2, 'msg' => $config['error']['invalidwebm']);
+
+ if ($ffprobe_out['format']['duration'] > $config['webm']['max_length'])
+ return array('code' => 4, 'msg' => $config['error']['webmtoolong']);
+}
+
+function make_webm_thumbnail($filename, $thumbnail, $width, $height) {
+ global $board, $config;
+
+ $filename = escapeshellarg($filename);
+ $thumbnail = escapeshellarg($thumbnail); // Should be safe by default but you
+ // can never be too safe.
+
+ $ffmpeg = $config['webm']['ffmpeg_path'];
+ $ffmpeg_out = array();
+
+ exec("$ffmpeg -i $filename -v quiet -ss 00:00:00 -an -vframes 1 -f mjpeg -vf scale=$width:$height $thumbnail 2>&1");
+
+ return count($ffmpeg_out);
+}
diff --git a/inc/lib/webm/posthandler.php b/inc/lib/webm/posthandler.php
index 1f831f5a..308c7507 100644
--- a/inc/lib/webm/posthandler.php
+++ b/inc/lib/webm/posthandler.php
@@ -6,6 +6,34 @@ function postHandler($post) {
global $board, $config;
if ($post->has_file) foreach ($post->files as &$file) if ($file->extension == 'webm') {
+ if ($config['webm']['use_ffmpeg']) {
+ require_once dirname(__FILE__) . '/ffmpeg.php';
+ $webminfo = get_webm_info($file->file_path);
+
+ if (empty($webminfo['error'])) {
+ $file->width = $webminfo['width'];
+ $file->height = $webminfo['height'];
+
+ if ($config['spoiler_images'] && isset($_POST['spoiler'])) {
+ $file = webm_set_spoiler($file);
+ }
+ else {
+ $file = set_thumbnail_dimensions($post, $file);
+ $tn_path = $board['dir'] . $config['dir']['thumb'] . $file->file_id . '.jpg';
+
+ if(empty(make_webm_thumbnail($file->file_path, $tn_path, $file->thumbwidth, $file->thumbheight))) {
+ $file->thumb = $file->file_id . '.jpg';
+ }
+ else {
+ $file->thumb = 'file';
+ }
+ }
+ }
+ else {
+ return $webminfo['error']['msg'];
+ }
+ }
+ else {
require_once dirname(__FILE__) . '/videodata.php';
$videoDetails = videoData($file->file_path);
if (!isset($videoDetails['container']) || $videoDetails['container'] != 'webm') return "not a WebM file";
@@ -14,10 +42,7 @@ function postHandler($post) {
$thumbName = $board['dir'] . $config['dir']['thumb'] . $file->file_id . '.webm';
if ($config['spoiler_images'] && isset($_POST['spoiler'])) {
// Use spoiler thumbnail
- $file->thumb = 'spoiler';
- $size = @getimagesize($config['spoiler_image']);
- $file->thumbwidth = $size[0];
- $file->thumbheight = $size[1];
+ $file = webm_set_spoiler($file);
} elseif (isset($videoDetails['frame']) && $thumbFile = fopen($thumbName, 'wb')) {
// Use single frame from video as pseudo-thumbnail
fwrite($thumbFile, $videoDetails['frame']);
@@ -33,17 +58,40 @@ function postHandler($post) {
if (isset($videoDetails['width']) && isset($videoDetails['height'])) {
$file->width = $videoDetails['width'];
$file->height = $videoDetails['height'];
+
if ($file->thumb != 'file' && $file->thumb != 'spoiler') {
- $thumbMaxWidth = $post->op ? $config['thumb_op_width'] : $config['thumb_width'];
- $thumbMaxHeight = $post->op ? $config['thumb_op_height'] : $config['thumb_height'];
- if ($videoDetails['width'] > $thumbMaxWidth || $videoDetails['height'] > $thumbMaxHeight) {
- $file->thumbwidth = min($thumbMaxWidth, intval(round($videoDetails['width'] * $thumbMaxHeight / $videoDetails['height'])));
- $file->thumbheight = min($thumbMaxHeight, intval(round($videoDetails['height'] * $thumbMaxWidth / $videoDetails['width'])));
- } else {
- $file->thumbwidth = $videoDetails['width'];
- $file->thumbheight = $videoDetails['height'];
+ $file = set_thumbnail_dimensions($post, $file);
}
}
}
}
}
+
+function set_thumbnail_dimensions($post,$file) {
+ global $board, $config;
+
+ $tn_dimensions = array();
+ $tn_maxw = $post->op ? $config['thumb_op_width'] : $config['thumb_width'];
+ $tn_maxh = $post->op ? $config['thumb_op_height'] : $config['thumb_height'];
+
+ if ($file->width > $tn_maxw || $file->height > $tn_maxh) {
+ $file->thumbwidth = min($tn_maxw, intval(round($file->width * $tn_maxh / $file->height)));
+ $file->thumbheight = min($tn_maxh, intval(round($file->height * $tn_maxw / $file->width)));
+ } else {
+ $file->thumbwidth = $file->width;
+ $file->thumbheight = $file->height;
+ }
+
+ return $file;
+}
+
+function webm_set_spoiler($file) {
+ global $board, $config;
+
+ $file->thumb = 'spoiler';
+ $size = @getimagesize($config['spoiler_image']);
+ $file->thumbwidth = $size[0];
+ $file->thumbheight = $size[1];
+
+ return $file;
+}
diff --git a/post.php b/post.php
index d6dfdaa1..033e5ab5 100644
--- a/post.php
+++ b/post.php
@@ -566,7 +566,9 @@ if (isset($_POST['delete'])) {
error($config['error']['nomove']);
}
- if ($output = shell_exec_error("cat $filenames | md5sum")) {
+ $md5cmd = $config['bsd_md5'] ? 'md5 -r' : 'md5sum';
+
+ if ($output = shell_exec_error("cat $filenames | $md5cmd")) {
$explodedvar = explode(' ', $output);
$hash = $explodedvar[0];
$post['filehash'] = $hash;
@@ -925,4 +927,3 @@ if (isset($_POST['delete'])) {
error($config['error']['nopost']);
}
}
-