aboutsummaryrefslogtreecommitdiff
path: root/transcoders/video_ffmpeg_php.inc
blob: f22c6cb699fa5716c6d256507c9844ee4a6ee7da (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
<?php

/*
 * @file
 * Transcoder class file to handle ffmpeg settings and conversions.
 */

// Make sure that the parent class is included.
include_once 'video_ffmpeg.inc';

class video_ffmpeg_php extends video_ffmpeg implements transcoder_interface {

  // Naming for our radio options. Makes it easy to extend our transcoders.
  private $name  = 'FFMPEG-PHP (Use ffmpeg-php when possible)';
  private $value = 'video_ffmpeg_php';

  /**
   * Constructor. Just call the parent.
   */
  public function __construct() {
    parent::__construct();
  }

  /**
   * Load a movie.
   *
   * @param $videopath
   *   Video file path.
   *
   * @return
   *   An ffmpeg_movie object on success, FALSE otherwise.
   */
  private function load_movie($videopath) {
    if(!extension_loaded('ffmpeg')) {
      $error_msg = t("Extension ffmpeg-php not available.");
      watchdog('transcoder', $error_msg, array(), WATCHDOG_ERROR);
      return FALSE;
    }

    return new ffmpeg_movie($videopath);
  }

  /**
   * Generate video thumbs.
   */
  public function generate_thumbnails($video) {
    global $user;
    // Setup our thmbnail path.
    $video_thumb_path = variable_get('video_thumb_path', 'videos/thumbnails');
    // Get the file system directory.
    // @todo : get the field file system settings to this
    $schema_thumb_path = file_default_scheme() . '://' . $video_thumb_path . '/' . $video['fid'];
    file_prepare_directory($schema_thumb_path, FILE_CREATE_DIRECTORY);
    // Total thumbs to generate
    $total_thumbs = variable_get('video_thumbs', 5);
    $videofile = file_load($video['fid']);
    //get the actual video file path from the stream wrappers
    $videopath = drupal_realpath($videofile->uri);
    //get the playtime from the current transcoder
    $duration = $this->get_playtime($videopath);

    $files = array();
    for ($i = 1; $i <= $total_thumbs; $i++) {
      $seek = ($duration / $total_thumbs) * $i - 1;  //adding minus one to prevent seek times equaling the last second of the video
      $filename = file_munge_filename("video-thumb-" . $video['fid'] . "-$i.jpg", '', TRUE);
      $thumbfile = $schema_thumb_path . '/' . $filename;
      //skip files already exists, this will save ffmpeg traffic
      if (!is_file(drupal_realpath($thumbfile))) {
        // Use PHP-FFMPEG
        $movie = $this->load_movie($videopath);

        if (!$movie) {
          return $files;
        }

        $frames = $movie->getFrameCount();
        $fps    = $movie->getFrameRate();

        // Get the right frame number
        $framenumber = (int) $seek * $fps;
        if ($framenumber > $frames) {
          $framenumber = $frames;
        }

        // Get the frame and create thumb file
        $frame = $movie->getFrame($framenumber);

        if (!$frame || !imagejpeg($frame->toGDImage(), drupal_realpath($thumbfile))) {
          $error_param = array('%file' => $thumbfile);
          $error_msg = t("Error generating thumbnail for video: generated file %file does not exist.", $error_param);
          // Log the error message.
          watchdog('transcoder', $error_msg, array(), WATCHDOG_ERROR);
          continue;
        }
      }
      // Begin building the file object.
      // @TODO : use file_munge_filename()
      $file = new stdClass();
      $file->uid = $user->uid;
      $file->status = 0;
      $file->filename = trim($filename);
      $file->uri = $thumbfile;
      $file->filemime = file_get_mimetype($filename);
      $file->filesize = filesize(drupal_realpath($thumbfile));
      $file->timestamp = time();
      $files[] = $file;
    }
    return $files;
  }

  /**
   * Return the playtime seconds of a video
   */
  public function get_playtime($video) {
    $movie = $this->load_movie($video);
    return (!$movie) ? 0 : $movie->getDuration();
  }

  /**
   * Return the dimensions of a video
   */
  public function get_dimensions($video) {
    $movie         = $this->load_movie($video);

    if (!$movie) {
      return array(
        'width'  => 0,
        'height' => 0,
        );
    }

    $res['width']  = $movie->getFrameWidth();
    $res['height'] = $movie->getFrameHeight();
    return $res;
  }

  /**
   * Interface Implementations
   * @see sites/all/modules/video/includes/transcoder_interface#get_name()
   */
  public function get_name() {
    return $this->name;
  }

  /**
   * Interface Implementations
   * @see sites/all/modules/video/includes/transcoder_interface#get_value()
   */
  public function get_value() {
    return $this->value;
  }

  /**
   * Interface Implementations
   * @see sites/all/modules/video/includes/transcoder_interface#get_help()
   */
  public function get_help() {
    return l(t('FFMPEG-PHP Online Manual'), 'http://ffmpeg-php.sourceforge.net/');
  }

  /**
   * Interface Implementations
   * @see sites/all/modules/video/includes/transcoder_interface#admin_settings()
   */
  public function admin_settings() {
    return parent::admin_settings();
  }

  /**
   * Interface Implementations
   * @see sites/all/modules/video/includes/transcoder_interface#admin_settings_validate()
   */
  public function admin_settings_validate($form, &$form_state) {
    return;
  }

  /**
   * Interface Implementations
   * @see sites/all/modules/video/includes/transcoder_interface#create_job()
   */
  public function create_job($video, $nid) {
    return parent::create_job($video, $nid);
  }

  /**
   * Interface Implementations
   * @see sites/all/modules/video/includes/transcoder_interface#delete_job()
   */
  public function delete_job($video) {
    return parent::delete_job($video);
  }

  /**
   * Interface Implementations
   * @see sites/all/modules/video/includes/transcoder_interface#load_job()
   */
  public function load_job($fid) {
    return parent::load_job($fid);
  }

  /**
   * Interface Implementations
   * @see sites/all/modules/video/includes/transcoder_interface#load_job_queue()
   */
  public function load_job_queue() {
    return parent::load_job_queue();
  }

  /**
   * Interface Implementations
   * @see sites/all/modules/video/includes/transcoder_interface#load_completed_job()
   */
  public function load_completed_job(&$video) {
    return parent::load_completed_job($video);
  }

}