Video Embed & Thumbnail Generator - Version 0.2

Version Description

Download this release

Release Info

Developer kylegilman
Plugin Icon 128x128 Video Embed & Thumbnail Generator
Version 0.2
Comparing to
See all releases

Version 0.2

expressinstall.swf ADDED
Binary file
images/AndroidPlay.png ADDED
Binary file
images/androidthumb.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ header('content-type: image/jpeg');
4
+
5
+ function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct){
6
+ $opacity=$pct;
7
+ // getting the watermark width
8
+ $w = imagesx($src_im);
9
+ // getting the watermark height
10
+ $h = imagesy($src_im);
11
+
12
+ // creating a cut resource
13
+ $cut = imagecreatetruecolor($src_w, $src_h);
14
+ // copying that section of the background to the cut
15
+ imagecopy($cut, $dst_im, 0, 0, $dst_x, $dst_y, $src_w, $src_h);
16
+ // inverting the opacity
17
+ $opacity = 100 - $opacity;
18
+
19
+ // placing the watermark now
20
+ imagecopy($cut, $src_im, 0, 0, $src_x, $src_y, $src_w, $src_h);
21
+ imagecopymerge($dst_im, $cut, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $opacity);
22
+ }
23
+
24
+
25
+ $watermark = imagecreatefrompng('AndroidPlay.png');
26
+ $watermark_width = imagesx($watermark);
27
+ $watermark_height = imagesy($watermark);
28
+ $image = imagecreatetruecolor($watermark_width, $watermark_height);
29
+ $image = imagecreatefromjpeg($_GET['src']);
30
+ $size = getimagesize($_GET['src']);
31
+ $dest_x = $size[0] / 2 - ($watermark_width / 2) ;
32
+ $dest_y = $size[1] / 2 - ($watermark_height / 2);
33
+ imagecopymerge_alpha($image, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, 0);
34
+ imagejpeg($image);
35
+ imagedestroy($image);
36
+ imagedestroy($watermark);
37
+ ?>
images/cameranoise_logo.png ADDED
Binary file
kg_callffmpeg.php ADDED
@@ -0,0 +1,230 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $ffmpegPath = $_POST['ffmpeg']."/ffmpeg";
4
+ $movieurl = $_POST['movieurl'];
5
+ $numberofthumbs = $_POST['numberofthumbs'];
6
+ $randomize = $_POST['randomize'];
7
+ $action = $_POST['action'];
8
+ $poster = $_POST['poster'];
9
+ $uploads = $_POST['uploads'];
10
+
11
+ $moviefilepath = str_replace(" ", "%20", $movieurl);
12
+ $movie_extension = pathinfo(parse_url($movieurl, PHP_URL_PATH), PATHINFO_EXTENSION);
13
+ $moviefilebasename = basename($movieurl,'.'.$movie_extension);
14
+ $moviefilebasename = str_replace(" ", "_", $moviefilebasename);
15
+ $thumbnailfilebase = $uploads[url]."/thumb_tmp/".$moviefilebasename;
16
+
17
+ class Process{
18
+ private $pid;
19
+ private $command;
20
+
21
+ public function __construct($cl=false){
22
+ if ($cl != false){
23
+ $this->command = $cl;
24
+ $this->runCom();
25
+ }
26
+ }
27
+ private function runCom(){
28
+ $command = 'nohup '.$this->command.' > /dev/null 2>&1 & echo $!';
29
+ exec($command ,$op);
30
+ $this->pid = (int)$op[0];
31
+ }
32
+
33
+ public function setPid($pid){
34
+ $this->pid = $pid;
35
+ }
36
+
37
+ public function getPid(){
38
+ return $this->pid;
39
+ }
40
+
41
+ public function status(){
42
+ $command = 'ps -p '.$this->pid;
43
+ exec($command,$op);
44
+ if (!isset($op[1]))return false;
45
+ else return true;
46
+ }
47
+
48
+ public function start(){
49
+ if ($this->command != '')$this->runCom();
50
+ else return true;
51
+ }
52
+
53
+ public function stop(){
54
+ $command = 'kill '.$this->pid;
55
+ exec($command);
56
+ if ($this->status() == false)return true;
57
+ else return false;
58
+ }
59
+ }// class Process
60
+
61
+
62
+ /**
63
+ * Get the dimensions of a video file
64
+ *
65
+ * @param unknown_type $video
66
+ * @return array(width,height)
67
+ * @author Jamie Scott
68
+ */
69
+ function get_video_dimensions($video = false) {
70
+ global $ffmpegPath;
71
+ $command = $ffmpegPath . ' -i ' . $video . ' -vstats 2>&1';
72
+
73
+ exec ( $command, $output );
74
+ $output = implode("\n", $output);
75
+
76
+ $result = ereg ( '[0-9]?[0-9][0-9][0-9]x[0-9][0-9][0-9][0-9]?', $output, $regs );
77
+
78
+ if (isset ( $regs [0] )) {
79
+ $vals = (explode ( 'x', $regs [0] ));
80
+ $width = $vals [0] ? $vals [0] : null;
81
+ $height = $vals [1] ? $vals [1] : null;
82
+ preg_match('/Duration: (.*?),/', $output, $matches);
83
+ $duration = $matches[1];
84
+ preg_match('/configuration: (.*?)\n/', $output, $matches);
85
+ $configuration = $matches[1];
86
+ return array ('width' => $width, 'height' => $height, 'duration' => $duration, 'configuration' => $configuration );
87
+ } else {
88
+ return false;
89
+ }
90
+
91
+ }
92
+
93
+ function rrmdir($dir) {
94
+ if (is_dir($dir)) {
95
+ $objects = scandir($dir);
96
+ foreach ($objects as $object) {
97
+ if ($object != "." && $object != "..") {
98
+ if (filetype($dir."/".$object) == "dir") rrmdir($dir."/".$object); else unlink($dir."/".$object);
99
+ }
100
+ }
101
+ reset($objects);
102
+ rmdir($dir);
103
+ }
104
+ }
105
+
106
+
107
+ if ($action == generate || $action == encode ) {
108
+
109
+ exec($ffmpegPath.' /dev/null 2>&1', $output, $returnvalue); //attempt to execute FFMPEG
110
+
111
+ if ($returnvalue < 126 ) { //if FFMPEG executed
112
+
113
+ $movie_info = get_video_dimensions($moviefilepath);
114
+
115
+ if ($movie_info != false) { //if FFMPEG was able to open the file
116
+
117
+ $movie_duration_hours = intval(substr($movie_info['duration'], -11, 2));
118
+ $movie_duration_minutes = intval(substr($movie_info['duration'], -8, 2));
119
+ $movie_duration_seconds = intval(substr($movie_info['duration'], -5, 2));
120
+ $movie_duration_seconds = ($movie_duration_hours * 60 * 60) + ($movie_duration_minutes * 60) + $movie_duration_seconds;
121
+ $movie_width = $movie_info['width'];
122
+ $movie_height = $movie_info['height'];
123
+
124
+ if ($action == generate) {
125
+
126
+ //chdir($uploads['path']);
127
+ rrmdir($uploads['path'].'/thumb_tmp');
128
+ if (!file_exists($uploads['path'].'/thumb_tmp')) { mkdir($uploads['path'].'/thumb_tmp'); }
129
+ //foreach (glob($moviefilebasename."*.jpg") as $filename) {
130
+ // unlink($filename); // delete the old thumbnails
131
+ //}
132
+
133
+ $thumbnailheight = strval(round(floatval($movie_height) / floatval($movie_width) * 200));
134
+ $jpgpath = $uploads[path]."/thumb_tmp/";
135
+
136
+ $i = 1;
137
+ $increaser = 0;
138
+
139
+ while ($i <= $numberofthumbs) {
140
+
141
+ $iincreaser = $i + $increaser;
142
+ $movieoffset = round(($movie_duration_seconds * $iincreaser) / ($numberofthumbs * 2));
143
+
144
+ if ($randomize == 1) { //adjust offset random amount
145
+ $movieoffset = $movieoffset - rand(0, round($movie_duration_seconds / $numberofthumbs));
146
+ }
147
+
148
+ $thumbnailfilename[$i] = $jpgpath.$moviefilebasename.$i.".jpg";
149
+ $ffmpeg_options = "-ss $movieoffset -i ".$moviefilepath." -vframes 1 ".$thumbnailfilename[$i];
150
+ $thumbnailurl = $thumbnailfilebase.$i.'.jpg';
151
+
152
+ //$process = new Process($ffmpegPath." ".$ffmpeg_options);
153
+ //sleep(1);
154
+ exec($ffmpegPath." ".$ffmpeg_options);
155
+ $thumbnaildisplaycode = $thumbnaildisplaycode.'<div style="text-align:center; display:inline-block; margin:2px;"><label for="kgflashmedia-thumb'.$i.'"><img src="'.$thumbnailurl.'?'.rand().'" width="200" height="'.$thumbnailheight.'"></label><br /><input type="radio" name="kgflashmedia-thumb" id="kgflashmedia-thumb'.$i.'" value="'.str_replace('/thumb_tmp/', '/', $thumbnailurl).'" onchange="getElementById(\'kgflashmediaplayer-poster\').value = this.value;"></div>';
156
+
157
+ $increaser++;
158
+ $i++;
159
+ }
160
+
161
+ $arr = array ( "thumbnaildisplaycode"=>$thumbnaildisplaycode, "movie_width"=>$movie_width, "movie_height"=>$movie_height );
162
+
163
+ echo json_encode($arr);
164
+ }//if generate
165
+
166
+ if ($action == encode) {
167
+ $encodepath = $uploads[path]."/";
168
+ $ipodfilepath = $encodepath.$moviefilebasename."-ipod.m4v";
169
+ $ogvfilepath = $encodepath.$moviefilebasename.".ogv";
170
+
171
+ if ( ! file_exists($ipodfilepath) ) {
172
+ $ipod_movie_height = strval(round(floatval($movie_height) / floatval($movie_width) * 640));
173
+ if ( strpos($movie_info['configuration'], 'enable-libfaac') && strpos($movie_info['configuration'], 'enable-libx264') ) {
174
+ $ffmpeg_ipod_options = " -acodec libfaac -ab 128k -s 640x".$ipod_movie_height." -vcodec libx264 -vpre slow -vpre ipod640 -b 800k -bt 800k -threads 0 -f ipod ".$ipodfilepath;
175
+ echo "<strong> Encoding iPod... </strong>";
176
+ }//if the proper FFMPEG libraries are enabled
177
+ else { echo "<strong>FFMPEG missing library 'libfaac' or 'libx264' required for iPod encoding. </strong></strong>"; }
178
+ }//if iPod file doesn't already exist
179
+ else { echo "<strong>iPod Already Encoded! </strong>"; }
180
+
181
+ if ( ! file_exists($ogvfilepath) ) {
182
+ if ( strpos($movie_info['configuration'], 'enable-libvorbis') && strpos($movie_info['configuration'], 'enable-libtheora') ) {
183
+ $ogvbitrate = $movie_height * 3;
184
+ $ffmpeg_ogv_options = " -acodec libvorbis -ab 128k -vcodec libtheora -b ".$ogvbitrate."k -threads 0 ".$ogvfilepath;
185
+ echo "<strong> Encoding OGG... </strong>";
186
+ }//if the proper FFMPEG libraries are enabled
187
+ else { echo "<strong>FFMPEG missing library 'libvorbis' or 'libtheora' required for ogv encoding.</strong></strong>"; }
188
+ }//if ogv doesn't already exist
189
+ else { echo "<strong>OGG Already Encoded!</strong>"; }
190
+
191
+ if ( ! file_exists($ogvfilepath) || ! file_exists($ipodfilepath) ) {
192
+ $ffmpeg_options = "-i ".$moviefilepath.$ffmpeg_ipod_options.$ffmpeg_ogv_options;
193
+ $process = new Process($ffmpegPath." ".$ffmpeg_options);
194
+ }//if both HTML5 videos don't exist
195
+
196
+ }//if encode
197
+
198
+ }//if ffmpeg can open movie
199
+
200
+ else { $thumbnaildisplaycode = '<strong>Can\'t open movie file.</strong>' ;
201
+ $arr = array ( "thumbnaildisplaycode"=>$thumbnaildisplaycode );
202
+ echo json_encode($arr);
203
+ } //can't open movie
204
+
205
+ }//if ffmpeg exists
206
+
207
+ else { $thumbnaildisplaycode = '<strong>Error: FFMPEG not found. Verify that FFMPEG is installed and check the <a href="options-general.php?page=video-embed-thumbnail-generator.php">path to FFMPEG plugin setting</a>.</strong>' ;
208
+ $arr = array ( "thumbnaildisplaycode"=>$thumbnaildisplaycode );
209
+ echo json_encode($arr);
210
+ } //no ffmpeg
211
+
212
+
213
+ }// if encoding or generating
214
+
215
+ if ($action == delete) {
216
+
217
+ rrmdir($uploads['path'].'/thumb_tmp');
218
+ echo ("<strong>Thumbnails Deleted</strong>");
219
+
220
+ }//if delete
221
+
222
+ if ($action == submit) {
223
+
224
+ $posterfile = pathinfo($poster, PATHINFO_BASENAME);
225
+ copy($uploads['path'].'/thumb_tmp/'.$posterfile, $uploads['path'].'/'.$posterfile);
226
+ //rrmdir($uploads['path'].'/thumb_tmp');
227
+
228
+ }//if submit
229
+
230
+ ?>
kg_video_plugin.js ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // closure to avoid namespace collision
2
+
3
+ function tb_remove() {
4
+
5
+ jQuery.post(kg_plugin_dir + '/kg_callffmpeg.php', { action: 'delete', uploads: kg_upload_dir } );
6
+ jQuery("#TB_imageOff").unbind("click");
7
+ jQuery("#TB_closeWindowButton").unbind("click");
8
+ jQuery("#TB_window").fadeOut("fast",function(){jQuery('#TB_window,#TB_overlay,#TB_HideSelect').trigger("unload").unbind().remove();});
9
+ jQuery("#TB_load").remove();
10
+ if (typeof document.body.style.maxHeight == "undefined") {//if IE 6
11
+ $("body","html").css({height: "auto", width: "auto"});
12
+ $("html").css("overflow","");
13
+ }
14
+ document.onkeydown = "";
15
+ document.onkeyup = "";
16
+ jQuery('#thumbnailplaceholder').empty();
17
+ jQuery('#html5placeholder').empty();
18
+ jQuery('#kgflashmediaplayer-poster').val("");
19
+ return false;
20
+
21
+ }
22
+
23
+
24
+ (function(){
25
+ // creates the plugin
26
+ tinymce.create('tinymce.plugins.kgvideoplayer', {
27
+ // creates control instances based on the control's id.
28
+ // our button's id is "kgvideoplayer_button"
29
+ createControl : function(id, controlManager) {
30
+ if (id == 'kgvideoplayer_button') {
31
+ // creates the button
32
+ var button = controlManager.createButton('kgvideoplayer_button', {
33
+ title : 'Video Embed & Thumbnail Generator', // title of the button
34
+ image : kg_plugin_dir+'/images/cameranoise_logo.png', // path to the button's image
35
+ onclick : function() {
36
+ // triggers the thickbox
37
+ var width = jQuery(window).width(), H = jQuery(window).height(), W = ( 720 < width ) ? 720 : width;
38
+ W = W - 80;
39
+ H = H - 84;
40
+ tb_show( 'Video Embed & Thumbnail Generator', '#TB_inline?width=' + W + '&height=' + H + '&inlineId=kgflashmediaplayer-form' );
41
+ }
42
+ });
43
+ return button;
44
+ }
45
+ return null;
46
+ }
47
+ });
48
+
49
+ // registers the plugin. DON'T MISS THIS STEP!!!
50
+ tinymce.PluginManager.add('kgvideoplayer', tinymce.plugins.kgvideoplayer);
51
+
52
+ // executes this when the DOM is ready
53
+ jQuery(function(){
54
+ // creates a form to be displayed everytime the button is clicked
55
+ // you should achieve this using AJAX instead of direct html code like this
56
+
57
+ kg_aspect = (kg_height_option/kg_width_option);
58
+
59
+ var form = jQuery('<div id="kgflashmediaplayer-form"><table id="kgflashmediaplayer-table" class="form-table">\
60
+ <tr>\
61
+ <th><label for="videotitle">Video Title</label></th>\
62
+ <td><input type="text" id="videotitle" name="videotitle" value="" size="50" /><br />\
63
+ <small>Add an optional header above the video.</small></td>\
64
+ </tr>\
65
+ <tr>\
66
+ <th><label for="kgflashmediaplayer-url">Video URL</label></th>\
67
+ <td><input type="text" id="kgflashmediaplayer-url" name="url" value="" size="50" onchange="document.getElementById(\'html5placeholder\').innerHTML = \'\';"/><br />\
68
+ <small>Specify the URL of the video file you uploaded.</small></td>\
69
+ </tr>\
70
+ <tr><td colspan = "2"><div id="thumbnailplaceholder"></div></td></tr>\
71
+ <tr>\
72
+ <th><label for="numberofthumbs">Number of Thumbnails</label</th>\
73
+ <td><input type="text" id="numberofthumbs" name="numberofthumbs" value="3" size="3" maxlength="2" /><input type="button" id="thumbgenerate" class="button-secondary" value="Generate" name="thumbgenerate" /><input type="button" id="thumbrandomize" class="button-secondary" value="Randomize" name="thumbrandomize" /><!--<input type="button" id="thumbdelete" class="button-secondary" value="Delete" name="thumbdelete" />--></td>\
74
+ </tr>\
75
+ <tr>\
76
+ <th><label for="kgflashmediaplayer-poster">Poster URL</label></th>\
77
+ <td><input type="text" name="poster" id="kgflashmediaplayer-poster" value="" size="50" /><br />\
78
+ <small>Specify the URL of the poster image. Leave blank if you want to use the default.</small>\
79
+ </tr>\
80
+ <tr>\
81
+ <th><label for="kgflashmediaplayer-width">Width</label></th>\
82
+ <td><input type="text" name="width" id="kgflashmediaplayer-width" value="'+kg_width_option+'" size="4" maxlength="4" onchange="if (document.getElementById(\'lockaspect\').checked == true) { document.getElementById(\'kgflashmediaplayer-height\').value=Math.round(this.value*kg_aspect); }" /> <input type="checkbox" name="lockaspect" id="lockaspect" checked> <label for="lockaspect"><small>Lock Aspect Ratio</small></label><br />\
83
+ <small>Specify the displayed width of the video.</small></td>\
84
+ </tr>\
85
+ <tr>\
86
+ <th><label for="kgflashmediaplayer-height">Height</label></th>\
87
+ <td><input type="text" name="height" id="kgflashmediaplayer-height" value="'+kg_height_option+'" onchange="if (document.getElementById(\'lockaspect\').checked == true) { document.getElementById(\'kgflashmediaplayer-width\').value=Math.round(this.value/kg_aspect); }" size="4" maxlength="4" /><br />\
88
+ <small>Specify the displayed height of the video.</small></td>\
89
+ </tr>\
90
+ <tr>\
91
+ <th><label for="downloadlink">Include Download Link</label></th>\
92
+ <td><input type="checkbox" name="downloadlink" id="downloadlink" value="true" /><br /></td>\
93
+ </tr>\
94
+ <tr><td colspan = "2"><input type="button" id="html5" class="button-secondary" value="Generate HTML5 Videos" name="html5" /><div id="html5placeholder" style="display:inline-block;"></div></td></tr>\
95
+ </table>\
96
+ <p class="submit">\
97
+ <input type="button" id="kgflashmediaplayer-submit" class="button-primary" value="Insert Flash Media Player" name="submit" />\
98
+ </p>\
99
+ </div>');
100
+
101
+ var table = form.find('table');
102
+ form.appendTo('body').hide();
103
+
104
+ //handles the click event of the generate button
105
+ form.find('#thumbgenerate').click(function(){
106
+ jQuery('#thumbnailplaceholder').empty();
107
+ jQuery('#thumbnailplaceholder').append('<strong>Loading...</strong>');
108
+ jQuery.post(kg_plugin_dir + '/kg_callffmpeg.php', { movieurl: table.find('#kgflashmediaplayer-url').val(), numberofthumbs: table.find('#numberofthumbs').val(), action: 'generate', ffmpeg: kg_ffmpeg_path, uploads: kg_upload_dir }, function(data) {
109
+ jQuery('#thumbnailplaceholder').empty();
110
+ jQuery('#thumbnailplaceholder').append(data.thumbnaildisplaycode);
111
+ kg_aspect = data.movie_height/data.movie_width;
112
+ if (parseInt(data.movie_width) < parseInt(kg_width_option) ) { jQuery('#kgflashmediaplayer-width').val(data.movie_width); }
113
+ else { jQuery('#kgflashmediaplayer-width').val(kg_width_option); }
114
+ if (parseInt(data.movie_width) > parseInt(kg_width_option) ) { jQuery('#kgflashmediaplayer-height').val(Math.round(kg_aspect*kg_width_option)); }
115
+ else { jQuery('#kgflashmediaplayer-height').val(data.movie_height); }
116
+ }, "json");
117
+ });
118
+
119
+ //handles the click event of the randomize button
120
+ form.find('#thumbrandomize').click(function(){
121
+ jQuery('#thumbnailplaceholder').empty();
122
+ jQuery('#thumbnailplaceholder').append('<strong>Loading...</strong>');
123
+ jQuery.post(kg_plugin_dir + '/kg_callffmpeg.php', { movieurl: table.find('#kgflashmediaplayer-url').val(), numberofthumbs: table.find('#numberofthumbs').val(), randomize: '1', action: 'generate', ffmpeg: kg_ffmpeg_path, uploads: kg_upload_dir }, function(data) {
124
+ jQuery('#thumbnailplaceholder').empty();
125
+ jQuery('#thumbnailplaceholder').append(data.thumbnaildisplaycode);
126
+ kg_aspect = data.movie_height/data.movie_width;
127
+ if (parseInt(data.movie_width) < parseInt(kg_width_option) ) { jQuery('#kgflashmediaplayer-width').val(data.movie_width); }
128
+ else { jQuery('#kgflashmediaplayer-width').val(kg_width_option); }
129
+ if (parseInt(data.movie_width) > parseInt(kg_width_option) ) { jQuery('#kgflashmediaplayer-height').val(Math.round(kg_aspect*kg_width_option)); }
130
+ else { jQuery('#kgflashmediaplayer-height').val(data.movie_height); }
131
+ }, "json");
132
+ //jQuery('#thumbnailplaceholder').load(kg_plugin_dir + '/kg_callffmpeg.php', { movieurl: table.find('#kgflashmediaplayer-url').val(), action: 'generate', poster: table.find('#kgflashmediaplayer-poster').val(), uploads: kg_upload_dir, ffmpeg: kg_ffmpeg_path, numberofthumbs: table.find('#numberofthumbs').val() } );
133
+ });
134
+
135
+ //handles the click event of the delete button
136
+ form.find('#thumbdelete').click(function(){
137
+ jQuery('#thumbnailplaceholder').empty();
138
+ jQuery('#thumbnailplaceholder').append('<strong>Deleting...</strong>');
139
+ jQuery('#thumbnailplaceholder').load(kg_plugin_dir + '/kg_callffmpeg.php', { movieurl: table.find('#kgflashmediaplayer-url').val(), action: 'delete', poster: table.find('#kgflashmediaplayer-poster').val(), uploads: kg_upload_dir } );
140
+ });
141
+
142
+ //handles the click event of the HTML5 button
143
+ form.find('#html5').click(function(){
144
+ jQuery('#html5placeholder').empty();
145
+ jQuery('#html5placeholder').load(kg_plugin_dir + '/kg_callffmpeg.php', { movieurl: table.find('#kgflashmediaplayer-url').val(), action: 'encode', ffmpeg: kg_ffmpeg_path, uploads: kg_upload_dir } );
146
+ });
147
+
148
+ // handles the click event of the submit button
149
+ form.find('#kgflashmediaplayer-submit').click(function(){
150
+ //delete unused thumbnails
151
+ jQuery.post(kg_plugin_dir + '/kg_callffmpeg.php', { movieurl: table.find('#kgflashmediaplayer-url').val(), action:'submit', poster:table.find('#kgflashmediaplayer-poster').val(), uploads: kg_upload_dir }, function(data) {
152
+ //jQuery('#thumbnailplaceholder').append(data.thumbnaildisplaycode);
153
+ jQuery('#thumbnailplaceholder').empty();
154
+ }, "json" );
155
+
156
+ // defines the options and their default values
157
+ // again, this is not the most elegant way to do this
158
+ // but well, this gets the job done nonetheless
159
+ var options = {
160
+ 'url' : '',
161
+ 'poster' : '',
162
+ 'width' : '',
163
+ 'height' : ''
164
+ };
165
+
166
+ var videotitle = '<p><strong>' + table.find('#videotitle').val() + '</strong></p>';
167
+ var shortcode = '[FMP';
168
+
169
+ for( var index in options) {
170
+ var value = table.find('#kgflashmediaplayer-' + index).val();
171
+
172
+ // attaches the attribute to the shortcode only if it's different from the default value
173
+ if ( value !== options[index] )
174
+ if ( index !== 'url' )
175
+ shortcode += ' ' + index + '="' + value + '"';
176
+ }
177
+
178
+ shortcode += ']' + table.find('#kgflashmediaplayer-url').val();
179
+ shortcode += '[/FMP]';
180
+ if ( document.getElementById('downloadlink').checked == true )
181
+ shortcode += '<p><a href="' + table.find('#kgflashmediaplayer-url').val() + '">Right-click this link to download</a></p>';
182
+
183
+ // inserts the shortcode into the active editor
184
+ if ( table.find('#videotitle').val() !== "")
185
+ tinyMCE.activeEditor.execCommand('mceInsertContent', 0, videotitle);
186
+
187
+ tinyMCE.activeEditor.execCommand('mceInsertContent', 0, shortcode);
188
+
189
+ // closes Thickbox
190
+ tb_remove();
191
+ });
192
+
193
+ });
194
+ })()
readme.txt ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Plugin Name ===
2
+ Contributors: kylegilman
3
+ Tags: video, html5, shortcode, thumbnail
4
+ Requires at least: 3.0
5
+ Tested up to: 3.2.1
6
+ Stable tag: 0.2
7
+
8
+ Generates thumbnails, HTML5-compliant videos, and embed codes for locally hosted videos. Requires FFMPEG for thumbnails and encodes.
9
+
10
+ == Description ==
11
+
12
+ A plugin for the WordPress visual editor to make embedding videos, generating thumbnails, and encoding HTML5-compliant files a little bit easier.
13
+
14
+ The plugin adds a button to the visual editor in WordPress. The icon has a generic man & woman icon with a camera between them. Press the button to open the plugin's dialog box.
15
+
16
+ For now you’ll have to upload the video separately, then enter the URL into the Video URL box. The embedded player will default to a Flash video player, so it should be a Flash Video compatible file. You should be able to use FLV, but I haven’t tested it, so I strongly recommend H.264 video and AAC audio in an MP4 container. If you’re using Apple’s Compressor, the “Streaming” setting should be “Fast Start” (NOT Fast Start – Compressed Header).
17
+
18
+ The plugin uses FFMPEG to generate thumbnails and encode HTML5 videos. By default the plugin looks for FFMPEG in /usr/local/bin but if FFMPEG is installed in a different place on your server, you can point it to the correct place in the plugin settings.
19
+
20
+ If FFMPEG is installed on your server, you can generate thumbnails using either the “Generate” or “Randomize” buttons. The “Generate” button will always generate thumbnails from the same frames of your video. If you don’t like them you can randomize the results with the “Randomize” button. You can generate as many or as few as you need. The unused thumbnails will be deleted once you close the window.
21
+
22
+ In the plugin settings you can set the default maximum width based on the width of your particular template and those values will be filled in when you open the window. If you generate thumbnails, the video display dimensions will be automatically adjusted to match the size and aspect ratio of the video file. You can make further adjustments if you want.
23
+
24
+ The “Generate HTML5 Videos” button is still a bit experimental. If you have FFMPEG on your server, clicking the button will start encoding an iPod/iPad/Android compliant H.264 video (which will also work in Safari and current versions of Chrome) and a Firefox-compatible OGV video. Anyone using a modern browser who doesn’t have a Flash plugin will see these files instead of the original. The files will encode in the background and will take several minutes to complete, depending on your server setup, and the length of your video. In this beta version if something goes wrong after the encode starts, the plugin will not tell you.
25
+
26
+ The plugin is currently favoring Flash instead of HTML5 because Flash works better in my experience. It’s a better user experience in most cases. I’m particularly not a fan of some browsers’ tendencies to auto-download HTML5 video elements. I eventually plan to include the option to favor HTML5.
27
+
28
+ Android viewers who don’t use Flash will see a play button superimposed on the thumbnail instead of the default still image.
29
+
30
+ If you want to make it easier for people to save the video to their computers, you can choose to include a link to download by checking the “Include Download Link”
31
+
32
+ Click “Insert Flash Media Player” and you’ll get a shortcode in the visual editor that looks like this:
33
+
34
+ `[FMP poster="http://www.kylegilman.net/wp-content/uploads/2011/01/Reel_11-10-10-web1.jpg" width="720" height="404"]http://www.kylegilman.net/videos/Reel 11-10-10-web.mp4[/FMP]`
35
+
36
+ Once you save the post, the thumbnail file will be registered in the WordPress media library and added to the post’s attachments. Thumbnails and HTML5 videos are saved in the current “uploads” directory. HTML5 videos are not yet registered with the media library.
37
+
38
+ I’m not really a software developer. I’m just a film editor with some time on his hands who wanted to post video for clients and wasn’t happy with the current state of any available software. But I want to really make this thing work, so please help me out by posting your feedback. I’m developing the plugin on a VPS and I haven’t tested it on any other FFMPEG-enabled servers yet, so I’m sure there are all kinds of things that only work because of my particular server setup.
39
+
40
+ == Installation ==
41
+
42
+ 1. Upload the unzipped folder `video-embed-thumbnail-generator` to the `/wp-content/plugins/` directory.
43
+ 1. Activate the plugin through the 'Plugins' menu in WordPress.
44
+ 1. Follow instructions on the Description page.
45
+
46
+ == Frequently Asked Questions ==
47
+
48
+ = I'm on shared hosting and can't install software. Does this work without FFMPEG? =
49
+
50
+ Some of it will work without FFMPEG. You can generate embed codes for your videos on any host because that part of the plugin is JavaScript running in your browser. Without FFMPEG you won't be able to generate thumbnails or generate HTML5 videos. There is no way around this. A program has to read the video files in order to generate the thumbnails, and FFMPEG is the best one I've found to do that.
51
+
52
+ = Why do I have to upload the video separately and then copy and paste the URL? =
53
+
54
+ Because I am not a great programmer, and this was too much for me to figure out. In the future I'm hoping to integrate the plugin with the upload dialog box to streamline the process.
55
+
56
+ == Screenshots ==
57
+
58
+ 1. The button added to the visual editor.
59
+ 2. Pressing the button opens a dialog box.
60
+ 3. An example of a fully-filled dialog box.
61
+
62
+ == Changelog ==
63
+
64
+ 0.2 First Release
screenshot-1.jpg ADDED
Binary file
screenshot-2.jpg ADDED
Binary file
screenshot-3.jpg ADDED
Binary file
video-embed-thumbnail-generator.php ADDED
@@ -0,0 +1,760 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Plugin Name: Video Embed & Thumbnail Generator
4
+ Plugin URI: http://www.kylegilman.net/2011/01/18/video-embed-thumbnail-generator-wordpress-plugin/
5
+ Description: Generate video thumbnails, HTML5-compliant videos, and video embed shortcodes. Some functions require FFMPEG.
6
+ Version: 0.2
7
+ Author: Kyle Gilman
8
+ Author URI: http://www.kylegilman.net/
9
+
10
+ This program is free software; you can redistribute it and/or modify
11
+ it under the terms of the GNU General Public License as published by
12
+ the Free Software Foundation; either version 2 of the License, or
13
+ any later version.
14
+
15
+ This program is distributed in the hope that it will be useful,
16
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ GNU General Public License for more details.
19
+
20
+ You should have received a copy of the GNU General Public License
21
+ along with this program; if not, write to the Free Software
22
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
+
24
+ 1) Includes Jeroen Wijering's FLV Media Player (Creative Commons "BY-NC-SA" License) v5.1
25
+ Website: http://www.jeroenwijering.com/?item=JW_FLV_Player
26
+ License: http://creativecommons.org/licenses/by-nc-sa/2.0/
27
+ 2) Includes Geoff Stearns' SWFObject Javascript Library (MIT License) v2.1
28
+ Website: http://code.google.com/p/swfobject/
29
+ License: http://www.opensource.org/licenses/mit-license.php
30
+ 3) Includes code adapted from Joshua Eldridge's Flash Media Player Plugin
31
+ Website: http://www.mac-dev.net/
32
+ 4) Includes code adapted from Gary Cao's Make Shortcodes User-Friendly tutorial
33
+ Website: http://www.wphardcore.com/2010/how-to-make-shortcodes-user-friendly/
34
+ */
35
+
36
+ if ( ! defined( 'ABSPATH' ) )
37
+ die( "Can't load this file directly" );
38
+
39
+
40
+ function url_exists($url) {
41
+ $hdrs = @get_headers($url);
42
+ return is_array($hdrs) ? preg_match('/^HTTP\\/\\d+\\.\\d+\\s+2\\d\\d\\s+.*$/',$hdrs[0]) : false;
43
+ }
44
+
45
+
46
+ class KGvideoplayer
47
+ {
48
+ function __construct() {
49
+ add_action( 'admin_init', array( $this, 'kg_action_admin_init' ) );
50
+ }
51
+
52
+ function kg_action_admin_init() {
53
+ // only hook up these filters if we're in the admin panel, and the current user has permission
54
+ // to edit posts and pages
55
+ if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) ) {
56
+ add_filter( 'mce_buttons', array( $this, 'filter_mce_button' ) );
57
+ add_filter( 'mce_external_plugins', array( $this, 'filter_mce_plugin' ) );
58
+ }
59
+ }
60
+
61
+ function filter_mce_button( $buttons ) {
62
+ // add a separation before our button, here our button's id is "kgvideoplayer_button"
63
+ array_push( $buttons, '|', 'kgvideoplayer_button' );
64
+ return $buttons;
65
+ }
66
+
67
+ function filter_mce_plugin( $plugins ) {
68
+ // this plugin file will work the magic of our button
69
+ $plugins['kgvideoplayer'] = plugin_dir_url( __FILE__ ) . 'kg_video_plugin.js';
70
+ return $plugins;
71
+ }
72
+ }
73
+
74
+ $kgvideoplayer = new KGvideoplayer();
75
+
76
+
77
+ class uagent_info
78
+ {
79
+ //Stores some info about the browser and device.
80
+ var $useragent = "";
81
+
82
+ //Stores info about what content formats the browser can display.
83
+ var $httpaccept = "";
84
+
85
+ // Standardized (and configurable) values for true and false.
86
+ var $true = 1;
87
+ var $false = 0;
88
+
89
+ // A long list of strings which provide clues
90
+ // about devices and capabilities.
91
+ var $deviceAndroid = 'android';
92
+
93
+
94
+ //**************************
95
+ //The constructor. Initializes several default variables.
96
+ function uagent_info()
97
+ {
98
+ $this->useragent = strtolower($_SERVER['HTTP_USER_AGENT']);
99
+ $this->httpaccept = strtolower($_SERVER['HTTP_ACCEPT']);
100
+ }
101
+
102
+ //**************************
103
+ //Returns the contents of the User Agent value, in lower case.
104
+ function Get_Uagent()
105
+ {
106
+ return $this->useragent;
107
+ }
108
+
109
+ function DetectAndroid()
110
+ {
111
+ if (stripos($this->useragent, $this->deviceAndroid) > -1)
112
+ return $this->true;
113
+ else
114
+ return $this->false;
115
+ }
116
+
117
+ }
118
+
119
+ define("wp_FMP_swfobject_default", "true", true);
120
+ define("wp_FMP_flashplayer_default", "<strong>Please upgrade Flash Player</strong> This content is shown when the user does not have a correct Flash Player version installed.", true);
121
+ define("wp_FMP_default_width", "480", true);
122
+ define("wp_FMP_default_height", "360", true);
123
+ define("wp_FMP_default_HTML5", "true", true);
124
+ define("wp_FMP_default_controlbar_style", "docked", true);
125
+ define("wp_FMP_default_poster", "", true);
126
+ define("wp_FMP_default_autohide", "true", true);
127
+ define("wp_FMP_default_autoplay", "false", true);
128
+ define("wp_FMP_default_loop", "false", true);
129
+ define("wp_FMP_default_playbutton", "true", true);
130
+ define("wp_FMP_default_http_streaming", "false", true);
131
+ define("wp_FMP_default_stream_type", "liveOrRecorded", true);
132
+ define("wp_FMP_default_scale_mode", "letterbox", true);
133
+ define("wp_FMP_default_bgcolor", "", true);
134
+ define("wp_FMP_default_configuration", "", true);
135
+ define("wp_FMP_default_skin", "", true);
136
+ define("wp_FMP_default_ffmpeg", "/usr/local/bin", true);
137
+
138
+ add_option(wp_FMP_swfobject, wp_FMP_swfobject_default, 'Embed SWFObject');
139
+ add_option(wp_FMP_flashplayer, wp_FMP_flashplayer_default, 'Flash Player not installed message');
140
+ add_option(wp_FMP_width, wp_FMP_default_width, 'Default video width');
141
+ add_option(wp_FMP_height, wp_FMP_default_height, 'Default video height');
142
+ add_option(wp_FMP_HTML5, wp_FMP_default_HTML5, 'HTML5 video fallback');
143
+ add_option(wp_FMP_controlbar_style, wp_FMP_default_controlbar_style, 'Default controlbar style');
144
+ add_option(wp_FMP_poster, wp_FMP_default_poster, 'Default poster image');
145
+ add_option(wp_FMP_autohide, wp_FMP_default_autohide, 'Default autohide behavior');
146
+ add_option(wp_FMP_autoplay, wp_FMP_default_autoplay, 'Default autoplay behavior');
147
+ add_option(wp_FMP_loop, wp_FMP_default_loop, 'Default loop behavior');
148
+ add_option(wp_FMP_playbutton, wp_FMP_default_playbutton, 'Default play button overlay behavior');
149
+ add_option(wp_FMP_http_streaming, wp_FMP_default_http_streaming, 'Default HTTP streaming behavior');
150
+ add_option(wp_FMP_stream_type, wp_FMP_default_stream_type, 'Default video type');
151
+ add_option(wp_FMP_scale_mode, wp_FMP_default_scale_mode, 'Default video scale mode');
152
+ add_option(wp_FMP_bgcolor, wp_FMP_default_bgcolor, 'Default video background color');
153
+ add_option(wp_FMP_configuration, wp_FMP_default_configuration, 'Default video configuration file');
154
+ add_option(wp_FMP_skin, wp_FMP_default_skin, 'Default video skin file');
155
+ add_option(wp_FMP_ffmpeg, wp_FMP_default_ffmpeg, 'Path to FFMPEG');
156
+
157
+ function addSWFObject() {
158
+ if(get_option(wp_FMP_swfobject) == "true") {
159
+ echo "\n<script src=\"http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js\" type=\"text/javascript\"></script>\n";
160
+ }
161
+ }
162
+
163
+
164
+ if (is_admin()) {
165
+ add_action('wp_print_scripts','KG_FMP_JS_VARS');
166
+ function KG_FMP_JS_VARS() {
167
+ ?>
168
+ <script type="text/javascript">
169
+ var kg_width_option= <?php echo json_encode(get_option('wp_FMP_width')); ?>;
170
+ var kg_height_option= <?php echo json_encode(get_option('wp_FMP_height')); ?>;
171
+ var kg_ffmpeg_path= <?php echo json_encode(get_option('wp_FMP_ffmpeg')); ?>;
172
+ var kg_plugin_dir= <?php echo json_encode(plugins_url("", __FILE__)); ?>;
173
+ var kg_upload_dir= <?php echo json_encode(wp_upload_dir()); ?>;
174
+ </script>
175
+ <?php
176
+ }
177
+ }
178
+
179
+
180
+ function FMP_shortcode($atts, $content = ''){
181
+
182
+ // workaround for relative video URL (contributed by Lee Fernandes)
183
+ if(substr($content, 0, 1) == '/') $content = get_bloginfo('url').$content;
184
+
185
+ $query_atts = shortcode_atts(
186
+ array('width' => get_option(wp_FMP_width),
187
+ 'height' => get_option(wp_FMP_height),
188
+ 'controlbar' => get_option(wp_FMP_controlbar_style),
189
+ 'autohide' => get_option(wp_FMP_autohide),
190
+ 'poster' => get_option(wp_FMP_poster),
191
+ 'playbutton' => get_option(wp_FMP_playbutton),
192
+ 'loop' => get_option(wp_FMP_loop),
193
+ 'autoplay' => get_option(wp_FMP_autoplay),
194
+ 'streamtype' => get_option(wp_FMP_stream_type),
195
+ 'scalemode' => get_option(wp_FMP_scale_mode),
196
+ 'backgroundcolor' => get_option(wp_FMP_bgcolor),
197
+ 'configuration' => get_option(wp_FMP_configuration),
198
+ 'skin' => get_option(wp_FMP_skin)), $atts);
199
+
200
+ $div_suffix = substr(uniqid(rand(), true),0,4);
201
+
202
+ if(get_option(wp_FMP_http_streaming) != "true") {
203
+ $video_swf = "http://fpdownload.adobe.com/strobe/FlashMediaPlayback.swf";
204
+ $minimum_flash = "10.0.0";
205
+ } else {
206
+ $video_swf = "http://fpdownload.adobe.com/strobe/FlashMediaPlayback_101.swf";
207
+ $minimum_flash = "10.1.0";
208
+ }
209
+
210
+ $flashvars = "{src:'".urlencode(trim($content))."'";
211
+
212
+ if($query_atts["controlbar"] != '') {
213
+ $flashvars .= ", controlBarMode:'".$query_atts["controlbar"]."'";
214
+ }
215
+ if($query_atts["autohide"] != '') {
216
+ $flashvars .= ", controlBarAutoHide:'".$query_atts["autohide"]."'";
217
+ }
218
+ if($query_atts["poster"] != '') {
219
+ $flashvars .= ", poster:'".$query_atts["poster"]."'";
220
+ }
221
+ if($query_atts["playbutton"] != '') {
222
+ $flashvars .= ", playButtonOverlay:'".$query_atts["playbutton"]."'";
223
+ }
224
+ if($query_atts["loop"] != '') {
225
+ $flashvars .= ", loop:'".$query_atts["loop"]."'";
226
+ }
227
+ if($query_atts["autoplay"] != '') {
228
+ $flashvars .= ", autoPlay:'".$query_atts["autoplay"]."'";
229
+ }
230
+ if($query_atts["streamtype"] != '') {
231
+ $flashvars .= ", streamType:'".$query_atts["streamtype"]."'";
232
+ }
233
+ if($query_atts["scalemode"] != '') {
234
+ $flashvars .= ", scaleMode:'".$query_atts["scalemode"]."'";
235
+ }
236
+ if($query_atts["backgroundcolor"] != '') {
237
+ $flashvars .= ", backgroundColor:'".$query_atts["backgroundcolor"]."'";
238
+ }
239
+ if($query_atts["configuration"] != '') {
240
+ $flashvars .= ", configuration:'".urlencode($query_atts["configuration"])."'";
241
+ }
242
+ if($query_atts["skin"] != '') {
243
+ $flashvars .= ", skin:'".urlencode($query_atts["skin"])."'";
244
+ }
245
+
246
+ $flashvars .= "}";
247
+
248
+ $params = "{allowfullscreen:'true', allowscriptaccess:'always'}";
249
+
250
+ if(get_option(wp_FMP_HTML5) == "true") {
251
+ $uagent_obj = new uagent_info();
252
+ $isAndroid = $uagent_obj->DetectAndroid(); //determine if we're running on an Android device
253
+ $encodedpath = dirname($query_atts["poster"]);
254
+ $moviefilebasename = pathinfo(trim($content), PATHINFO_FILENAME);
255
+ $moviefilebasename = str_replace(" ", "_", $moviefilebasename);
256
+ //$ipodurl = plugins_url('/encodes/'.$moviefilebasename.'-ipod.m4v', __FILE__);
257
+ //$ogvurl = plugins_url('/encodes/'.$moviefilebasename.'.ogv', __FILE__);
258
+ $ipodurl = $encodedpath."/".$moviefilebasename."-ipod.m4v";
259
+ $ogvurl = $encodedpath."/".$moviefilebasename.".ogv";
260
+ $code = "<div id=\"flashcontent".$div_suffix."\">";
261
+ $code .= "<video ";
262
+ if ($isAndroid) { $code .= "onclick='this.play();' "; }
263
+ $code .= "controls='controls'";
264
+ if($query_atts["poster"] != '' && !$isAndroid) {
265
+ $code .= " poster='".$query_atts["poster"]."' ";
266
+ }
267
+ if($query_atts["poster"] != '' && $isAndroid) {
268
+ $code .= " poster='".plugins_url('', __FILE__)."/images/androidthumb.php?src=".$query_atts["poster"]."' ";
269
+ }
270
+ $code .= " width='".$query_atts["width"]."' height='".$query_atts["height"]."'";
271
+ $code .= ">\n";
272
+ if (url_exists($ipodurl)) {
273
+ $code .= "<source src='".$ipodurl."'";
274
+ if (!$isAndroid) {
275
+ $code.= " type='video/mp4'";
276
+ }
277
+ $code .=">\n";
278
+ }
279
+ else { $code .= "<source src='".$content."' type='video/mp4'>\n"; }
280
+ if (url_exists($ogvurl)) { $code .= "<source src='".$ogvurl."' type='video/ogg'>\n"; }
281
+ $code .= "</video>\n";
282
+ $code .= "</div>\n\n";
283
+ } else {
284
+ $code = "<div id=\"flashcontent".$div_suffix."\">".get_option(wp_FMP_flashplayer)."</div>\n\n";
285
+ }
286
+
287
+ $code .= "<script type=\"text/javascript\">\n\t";
288
+ $code .= "swfobject.embedSWF('".$video_swf."', 'flashcontent".$div_suffix."', '".trim($query_atts['width'])."', '".trim($query_atts['height'])."', '".$minimum_flash."', '".plugins_url("", __FILE__)."/expressinstall.swf', $flashvars, $params)\n";
289
+
290
+ $code .= "</script>\n";
291
+
292
+ return $code;
293
+ }
294
+
295
+
296
+ function addFMPOptionsPage() {
297
+ add_options_page('Video Embed & Thumbnail Generator', 'Video Embed & Thumbnail Generator', 8, basename(__FILE__), 'FMPOptionsPage');
298
+ }
299
+
300
+ function FMPOptionsPage() {
301
+
302
+ if (isset($_POST['wp_FMP_reset'])) {
303
+ update_option(wp_FMP_swfobject, wp_FMP_swfobject_default);
304
+ update_option(wp_FMP_HTML5, wp_FMP_default_HTML5);
305
+ update_option(wp_FMP_width, wp_FMP_default_width);
306
+ update_option(wp_FMP_height, wp_FMP_default_height);
307
+ update_option(wp_FMP_flashplayer, wp_FMP_flashplayer_default);
308
+ update_option(wp_FMP_controlbar_style, wp_FMP_default_controlbar_style);
309
+ update_option(wp_FMP_poster, wp_FMP_default_poster);
310
+ update_option(wp_FMP_autohide, wp_FMP_default_autohide);
311
+ update_option(wp_FMP_autoplay, wp_FMP_default_autoplay);
312
+ update_option(wp_FMP_loop, wp_FMP_default_loop);
313
+ update_option(wp_FMP_playbutton, wp_FMP_default_playbutton);
314
+ update_option(wp_FMP_http_streaming, wp_FMP_default_http_streaming);
315
+ update_option(wp_FMP_stream_type, wp_FMP_default_stream_type);
316
+ update_option(wp_FMP_scale_mode, wp_FMP_default_scale_mode);
317
+ update_option(wp_FMP_bgcolor, wp_FMP_default_bgcolor);
318
+ update_option(wp_FMP_configuration, wp_FMP_default_configuration);
319
+ update_option(wp_FMP_skin, wp_FMP_default_skin);
320
+ update_option(wp_FMP_ffmpeg, wp_FMP_default_ffmpeg);
321
+
322
+ echo "<div class='updated'><p><strong>Flash Media Playback plugin reset to default settings</strong></p></div>";
323
+ }
324
+
325
+ if (isset($_POST['wp_FMP_update'])) {
326
+ check_admin_referer();
327
+ $use_swfobject = $_POST[wp_FMP_swfobject];
328
+ $use_html5fallback = $_POST[wp_FMP_HTML5];
329
+ $use_autohide = $_POST[wp_FMP_autohide];
330
+ $use_autoplay = $_POST[wp_FMP_autoplay];
331
+ $use_loop = $_POST[wp_FMP_loop];
332
+ $use_playbutton = $_POST[wp_FMP_playbutton];
333
+ $use_http_streaming = $_POST[wp_FMP_http_streaming];
334
+
335
+ if ($use_swfobject == 'use') {
336
+ update_option(wp_FMP_swfobject, "true");
337
+ } else {
338
+ update_option(wp_FMP_swfobject, "false");
339
+ }
340
+
341
+ if ($use_html5fallback == 'use') {
342
+ update_option(wp_FMP_HTML5, "true");
343
+ } else {
344
+ update_option(wp_FMP_HTML5, "false");
345
+ }
346
+
347
+ if ($use_autohide == 'use') {
348
+ update_option(wp_FMP_autohide, "true");
349
+ } else {
350
+ update_option(wp_FMP_autohide, "false");
351
+ }
352
+
353
+ if ($use_autoplay == 'use') {
354
+ update_option(wp_FMP_autoplay, "true");
355
+ } else {
356
+ update_option(wp_FMP_autoplay, "false");
357
+ }
358
+
359
+ if ($use_loop == 'use') {
360
+ update_option(wp_FMP_loop, "true");
361
+ } else {
362
+ update_option(wp_FMP_loop, "false");
363
+ }
364
+
365
+ if ($use_playbutton == 'use') {
366
+ update_option(wp_FMP_playbutton, "true");
367
+ } else {
368
+ update_option(wp_FMP_playbutton, "false");
369
+ }
370
+
371
+ if ($use_http_streaming == 'use') {
372
+ update_option(wp_FMP_http_streaming, "true");
373
+ } else {
374
+ update_option(wp_FMP_http_streaming, "false");
375
+ }
376
+
377
+ update_option(wp_FMP_width, $_POST[wp_FMP_width]);
378
+ update_option(wp_FMP_height, $_POST[wp_FMP_height]);
379
+ update_option(wp_FMP_bgcolor, $_POST[wp_FMP_bgcolor]);
380
+ update_option(wp_FMP_configuration, $_POST[wp_FMP_configuration]);
381
+ update_option(wp_FMP_skin, $_POST[wp_FMP_skin]);
382
+ update_option(wp_FMP_flashplayer, $_POST[wp_FMP_flashplayer]);
383
+ update_option(wp_FMP_controlbar_style, $_POST[wp_FMP_controlbar_style]);
384
+ update_option(wp_FMP_stream_type, $_POST[wp_FMP_stream_type]);
385
+ update_option(wp_FMP_scale_mode, $_POST[wp_FMP_scale_mode]);
386
+ update_option(wp_FMP_poster, $_POST[wp_FMP_poster]);
387
+ update_option(wp_FMP_ffmpeg, $_POST[wp_FMP_ffmpeg]);
388
+
389
+ echo "<div class='updated'><p><strong>Video Embed & Thumbnail Generator plugin settings updated</strong></p></div>";
390
+ }
391
+
392
+ ?>
393
+
394
+ <form method="post" action="options-general.php?page=video-embed-thumbnail-generator.php">
395
+ <div class="wrap">
396
+ <h2>Video Embed & Thumbnail Generator</h2>
397
+
398
+ <table class="form-table">
399
+ <tr>
400
+ <th colspan="2"><h3>Plugin settings</h3></th><td>
401
+ </td>
402
+ </tr>
403
+ <tr>
404
+ <th scope="row" valign="top" align="left">
405
+ <label>Embed SWFObject:</label>
406
+ </th>
407
+ <td width="10"></td>
408
+ <td>
409
+ <?php
410
+ echo "<input type='checkbox' name='wp_FMP_swfobject' id='wp_FMP_swfobject' value='use' ";
411
+ if(get_option(wp_FMP_swfobject) == "true") {
412
+ echo "checked";
413
+ }
414
+ echo " />\n";
415
+ ?>
416
+ Uncheck if you already have SWFObject embedded
417
+ </td>
418
+ </tr>
419
+ <tr>
420
+ <th scope="row" valign="top" align="left">
421
+ <label>Enable HTML5 video fallback:</label>
422
+ </th>
423
+ <td width="10"></td>
424
+ <td>
425
+ <?php
426
+ echo "<input type='checkbox' name='wp_FMP_HTML5' id='wp_FMP_HTML5' value='use' ";
427
+ if(get_option(wp_FMP_HTML5) == "true") {
428
+ echo "checked";
429
+ }
430
+ echo " />\n";
431
+ ?>
432
+ Uncheck if you don't want HTML5 video fallback.
433
+ </td>
434
+ </tr>
435
+ <tr>
436
+ <th scope="row" valign="top" align="left">
437
+ <label>Enable HTTP Streaming or Flash Access 2.0:</label>
438
+ </th>
439
+ <td width="10"></td>
440
+ <td>
441
+ <?php
442
+ echo "<input type='checkbox' name='wp_FMP_http_streaming' id='wp_FMP_http_streaming' value='use' ";
443
+ if(get_option(wp_FMP_http_streaming) == "true") {
444
+ echo "checked";
445
+ }
446
+ echo " />\n";
447
+ ?>
448
+ Check to support HTTP Streaming or Flash Access 2.0 (requires Flash Player 10.1)
449
+ </td>
450
+ </tr>
451
+ <tr>
452
+ <th scope="row" valign="top" align="left">
453
+ <label>Flash Player not installed message:</label>
454
+ </th>
455
+ <td width="10"></td>
456
+ <td>
457
+ <textarea name="wp_FMP_flashplayer" id="wp_FMP_flashplayer" rows="5" cols="50"><?php echo get_option(wp_FMP_flashplayer) ?></textarea><br />
458
+ <em>This message will only be shown if HTML5 video fallback is disabled</em>
459
+ </td>
460
+ </tr>
461
+ <tr align="left">
462
+ <th></th>
463
+ <td></td>
464
+ <td align="left"><br />
465
+ <div style="align:left"><input name="wp_FMP_update" value="Save Changes" type="submit" />&nbsp;&nbsp;&nbsp;<input name="wp_FMP_reset" value="Reset defaults" type="submit" /></div>
466
+ </td>
467
+ </tr>
468
+ <tr>
469
+ <th colspan="2"><h3>Default argument values</h3></th><td>
470
+ </td>
471
+ </tr>
472
+ <tr>
473
+ <th scope="row" valign="top" align="left">
474
+ <label>Path to FFMPEG:</label>
475
+ </th>
476
+ <td width="10"></td>
477
+ <td>
478
+ <input name="wp_FMP_ffmpeg" id="wp_FMP_ffmpeg" type="text" value="<?php echo get_option(wp_FMP_ffmpeg) ?>" /><br />
479
+ <em>Don't include trailing slash. Example: /usr/local/bin</em>
480
+ </td>
481
+ </tr>
482
+ <tr>
483
+ <th scope="row" valign="top" align="left">
484
+ <label>Default max video width:</label>
485
+ </th>
486
+ <td width="10"></td>
487
+ <td>
488
+ <input name="wp_FMP_width" id="wp_FMP_width" type="text" value="<?php echo get_option(wp_FMP_width) ?>" />
489
+ </td>
490
+ </tr>
491
+ <tr>
492
+ <th scope="row" valign="top" align="left">
493
+ <label>Default video height:</label>
494
+ </th>
495
+ <td width="10"></td>
496
+ <td>
497
+ <input name="wp_FMP_height" id="wp_FMP_height" type="text" value="<?php echo get_option(wp_FMP_height) ?>" />
498
+ </td>
499
+ </tr>
500
+ <tr>
501
+ <th scope="row" valign="top" align="left">
502
+ <label>Default background color:</label>
503
+ </th>
504
+ <td width="10"></td>
505
+ <td>
506
+ <input name="wp_FMP_bgcolor" id="wp_FMP_bgcolor" type="text" value="<?php echo get_option(wp_FMP_bgcolor) ?>" />
507
+ </td>
508
+ </tr>
509
+ <tr>
510
+ <th scope="row" valign="top" align="left">
511
+ <label>Default XML configuration file:</label>
512
+ </th>
513
+ <td width="10"></td>
514
+ <td>
515
+ <input name="wp_FMP_configuration" id="wp_FMP_configuration" type="text" size="50" value="<?php echo get_option(wp_FMP_configuration) ?>" />
516
+ </td>
517
+ </tr>
518
+ <tr>
519
+ <th scope="row" valign="top" align="left">
520
+ <label>Default video skin file:</label>
521
+ </th>
522
+ <td width="10"></td>
523
+ <td>
524
+ <input name="wp_FMP_skin" id="wp_FMP_skin" type="text" size="50" value="<?php echo get_option(wp_FMP_skin) ?>" />
525
+ </td>
526
+ </tr>
527
+ <tr>
528
+ <th scope="row" valign="top" align="left">
529
+ <label>Default video stream type:</label>
530
+ </th>
531
+ <td width="10"></td>
532
+ <td>
533
+ <select name="wp_FMP_stream_type" id="wp_FMP_stream_type">
534
+ <?php
535
+ $liveOrRecorded = "";
536
+ $live = "";
537
+ $recorded = "";
538
+ $dvr = "";
539
+
540
+ if(get_option(wp_FMP_stream_type) == "liveOrRecorded") {
541
+ $liveOrRecorded = " selected=\"selected\"";
542
+ }
543
+ if(get_option(wp_FMP_stream_type) == "live") {
544
+ $live = " selected=\"selected\"";
545
+ }
546
+ if(get_option(wp_FMP_stream_type) == "recorded") {
547
+ $recorded = " selected=\"selected\"";
548
+ }
549
+ if(get_option(wp_FMP_stream_type) == "dvr") {
550
+ $dvr = " selected=\"selected\"";
551
+ }
552
+
553
+ ?>
554
+ <option value="liveOrRecorded"<?php echo $liveOrRecorded ?>>live or recorded</option>
555
+ <option value="live"<?php echo $live ?>>live</option>
556
+ <option value="recorded"<?php echo $recorded ?>>recorded</option>
557
+ <option value="dvr"<?php echo $dvr ?>>DVR</option>
558
+ </select>
559
+ </td>
560
+ </tr>
561
+ <tr>
562
+ <th scope="row" valign="top" align="left">
563
+ <label>Default video scale mode:</label>
564
+ </th>
565
+ <td width="10"></td>
566
+ <td>
567
+ <select name="wp_FMP_scale_mode" id="wp_FMP_scale_mode">
568
+ <?php
569
+ $letterbox = "";
570
+ $none = "";
571
+ $stretch = "";
572
+ $zoom = "";
573
+
574
+ if(get_option(wp_FMP_scale_mode) == "letterbox") {
575
+ $letterbox = " selected=\"selected\"";
576
+ }
577
+ if(get_option(wp_FMP_scale_mode) == "none") {
578
+ $none = " selected=\"selected\"";
579
+ }
580
+ if(get_option(wp_FMP_scale_mode) == "stretch") {
581
+ $stretch = " selected=\"selected\"";
582
+ }
583
+ if(get_option(wp_FMP_scale_mode) == "zoom") {
584
+ $zoom = " selected=\"selected\"";
585
+ }
586
+
587
+ ?>
588
+ <option value="letterbox"<?php echo $letterbox ?>>letterbox</option>
589
+ <option value="none"<?php echo $none ?>>none</option>
590
+ <option value="stretch"<?php echo $stretch ?>>stretch</option>
591
+ <option value="zoom"<?php echo $zoom ?>>zoom</option>
592
+ </select>
593
+ </td>
594
+ </tr>
595
+ <tr>
596
+ <th scope="row" valign="top" align="left">
597
+ <label>Default controlbar style:</label>
598
+ </th>
599
+ <td width="10"></td>
600
+ <td>
601
+ <select name="wp_FMP_controlbar_style" id="wp_FMP_controlbar_style">
602
+ <?php
603
+ $docked = "";
604
+ $floating = "";
605
+ $none = "";
606
+ if(get_option(wp_FMP_controlbar_style) == "docked") {
607
+ $docked = " selected=\"selected\"";
608
+ }
609
+ if(get_option(wp_FMP_controlbar_style) == "floating") {
610
+ $floating = " selected=\"selected\"";
611
+ }
612
+ if(get_option(wp_FMP_controlbar_style) == "none") {
613
+ $none = " selected=\"selected\"";
614
+ }
615
+ ?>
616
+ <option value="docked"<?php echo $docked ?>>docked</option>
617
+ <option value="floating"<?php echo $floating ?>>floating</option>
618
+ <option value="none"<?php echo $none ?>>none</option>
619
+ </select>
620
+ </td>
621
+ </tr>
622
+ <tr>
623
+ <th scope="row" valign="top" align="left">
624
+ <label>Default poster image:</label>
625
+ </th>
626
+ <td width="10"></td>
627
+ <td>
628
+ <input type='text' name='wp_FMP_poster' id='wp_FMP_poster' size='50' value='<?php echo get_option(wp_FMP_poster) ?>' />
629
+ </td>
630
+ </tr>
631
+ <tr>
632
+ <th scope="row" valign="top" align="left">
633
+ <label>Default autohide behavior:</label>
634
+ </th>
635
+ <td width="10"></td>
636
+ <td>
637
+ <?php
638
+ echo "<input type='checkbox' name='wp_FMP_autohide' id='wp_FMP_autohide' value='use' ";
639
+ if(get_option(wp_FMP_autohide) == "true") {
640
+ echo "checked";
641
+ }
642
+ echo " />\n";
643
+ ?>
644
+ Uncheck if you do not want controlbar to hide when video is playing
645
+ </td>
646
+ </tr>
647
+ <tr>
648
+ <th scope="row" valign="top" align="left">
649
+ <label>Default autoplay behavior:</label>
650
+ </th>
651
+ <td width="10"></td>
652
+ <td>
653
+ <?php
654
+ echo "<input type='checkbox' name='wp_FMP_autoplay' id='wp_FMP_autoplay' value='use' ";
655
+ if(get_option(wp_FMP_autoplay) == "true") {
656
+ echo "checked";
657
+ }
658
+ echo " />\n";
659
+ ?>
660
+ Check if you want video to automatically play when loaded
661
+ </td>
662
+ </tr>
663
+ <tr>
664
+ <th scope="row" valign="top" align="left">
665
+ <label>Default loop behavior:</label>
666
+ </th>
667
+ <td width="10"></td>
668
+ <td>
669
+ <?php
670
+ echo "<input type='checkbox' name='wp_FMP_loop' id='wp_FMP_loop' value='use' ";
671
+ if(get_option(wp_FMP_loop) == "true") {
672
+ echo "checked";
673
+ }
674
+ echo " />\n";
675
+ ?>
676
+ Check if you want video to loop
677
+ </td>
678
+ </tr>
679
+ <tr>
680
+ <th scope="row" valign="top" align="left">
681
+ <label>Default play button overlay:</label>
682
+ </th>
683
+ <td width="10"></td>
684
+ <td>
685
+ <?php
686
+ echo "<input type='checkbox' name='wp_FMP_playbutton' id='wp_FMP_playbutton' value='use' ";
687
+ if(get_option(wp_FMP_playbutton) == "true") {
688
+ echo "checked";
689
+ }
690
+ echo " />\n";
691
+ ?>
692
+ Uncheck if you do not want a play button overlay
693
+ </td>
694
+ </tr>
695
+ <tr align="left">
696
+ <th></th>
697
+ <td></td>
698
+ <td align="left"><br />
699
+ <div style="align:left"><input name="wp_FMP_update" value="Save Changes" type="submit" />&nbsp;&nbsp;&nbsp;<input name="wp_FMP_reset" value="Reset defaults" type="submit" /></div><br />&nbsp;<br />
700
+ </td>
701
+ </tr>
702
+ </table>
703
+
704
+ </div>
705
+ </form>
706
+
707
+ <?php
708
+
709
+ }
710
+
711
+ function kg_addPostSave($post_id) {
712
+ global $flag;
713
+ if ($flag == 1) { //if draft already saved
714
+ $current_post = get_post($post_id);
715
+ preg_match_all('/poster="([^"\r\n]*)"/', $current_post->post_content, $matches);
716
+ $uploads = wp_upload_dir();
717
+
718
+ $post_children =& get_children('post_parent='.$post_id);
719
+ $existing_attachment = array();
720
+ $i=0;
721
+ foreach ($post_children as $child) {
722
+ $existing_attachment[$i] = $child->guid;
723
+ $i++;
724
+ }
725
+
726
+ foreach ($matches[1] as $url) {
727
+ if(!in_array($url, $existing_attachment)) {
728
+ $filename_baseurl = substr($url, 0, strlen($uploads['baseurl']));
729
+ if ( $filename_baseurl == $uploads['baseurl'] ) {
730
+ $filename = str_replace($filename_baseurl, $uploads['basedir'], $url);
731
+ if (file_exists($filename)) {
732
+ $wp_filetype = wp_check_filetype(basename($filename), null );
733
+ $attachment = array(
734
+ 'post_mime_type' => $wp_filetype['type'],
735
+ 'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
736
+ 'post_content' => '',
737
+ 'post_status' => 'inherit',
738
+ 'guid' => $url
739
+ );
740
+ $attach_id = wp_insert_attachment( $attachment, $filename, $post_id );
741
+ // you must first include the image.php file
742
+ // for the function wp_generate_attachment_metadata() to work
743
+ require_once(ABSPATH . "wp-admin" . '/includes/image.php');
744
+ $attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
745
+ wp_update_attachment_metadata( $attach_id, $attach_data );
746
+ }//if file exists
747
+ }//if url is in the uploads directory
748
+ }//if url is not already an attachment
749
+ }//foreach
750
+ }//if post not already saved
751
+ $flag = 1;
752
+ }
753
+
754
+ add_action('wp_head', 'addSWFObject');
755
+ add_action('admin_menu', 'addFMPOptionsPage');
756
+ add_action('save_post', 'kg_addPostSave');
757
+
758
+ add_shortcode('FMP', 'FMP_shortcode');
759
+
760
+ ?>