-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgetid3.module
318 lines (286 loc) · 10 KB
/
getid3.module
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
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
<?php
define('GETID3_RECOMMEND_VERSION', '1.8.2');
/**
* Implements hook_help().
*/
// function getid3_help($section, $arg) {
// switch ($section) {
// case 'admin/config/media/getid3':
// $help = '<p>' . t("To use this module you'll need to <a href='!download-link'>download the library</a> from the <a href='!info-link'>getID3 website</a> and extract the contents into the site's libraries directory. Currently, the recommended version of the getID3 library is %recommended-version.",
// array('!download-link' => url('http://prdownloads.sourceforge.net/getid3'), '!info-link' => url('http://getid3.org/'), '%recommended-version' => GETID3_RECOMMEND_VERSION)) . '</p>';
// return $help;
// }
// }
/**
* Implements hook_menu().
*/
function getid3_menu() {
$items['admin/config/media/getid3'] = array(
'title' => 'getID3()',
'description' => 'Configure settings associated with getID3().',
'page callback' => 'backdrop_get_form',
'page arguments' => array('getid3_admin_settings_form', NULL),
'access arguments' => array('administer site configuration'),
'file' => 'getid3.admin.inc',
);
return $items;
}
/**
* Implements hook_theme().
*/
function getid3_theme($existing, $type, $theme, $path) {
return array(
'getid3_duration' => array(
'variables' => array('duration' => NULL),
),
'getid3_sample_rate' => array(
'variables' => array('sample_rate' => NULL),
),
'getid3_bitrate' => array(
'variables' => array('bitrate' => NULL),
),
);
}
/**
* Implements hook_libraries_info().
*/
// function getid3_libraries_info() {
// $libraries['getid3'] = array(
// 'name' => 'getID3',
// 'vendor url' => 'http://www.getid3.org',
// 'download url' => 'http://sourceforge.net/projects/getid3/files/getID3%28%29%201.x/1.9.9/getID3-1.9.9-20141218.zip/download',
// 'path' => 'getid3',
// 'version' => '1.9.9', // @TODO: Move this into version_callback and version_arguments.
// 'files' => array(
// 'php' => array(
// 'getid3.php',
// ),
// ),
// );
// return $libraries;
// }
/**
* Load the getID3 library.
*
* @return
* Boolean indicating if the library was successfully loaded.
*/
// function getid3_load($display_warning = TRUE) {
// // Ensure the getID3() library is loaded.
// $library = libraries_detect('getid3');
// if ($library['installed']) {
// libraries_load('getid3');
// return TRUE;
// }
// return FALSE;
// }
/**
* Create and initialize an instance of getID3 class.
*/
function getid3_instance() {
$id3 = NULL;
// if (getid3_load()) {
$id3 = new getID3();
// MD5 is a big performance hit. Disable it by default.
$id3->option_md5_data = FALSE;
$id3->option_md5_data_source = FALSE;
$id3->encoding = 'UTF-8';
// }
return $id3;
}
/**
* Takes a file entity object and returns ID3 data.
* @param $file
* @return null|array
*/
function getid3_analyze_file($file) {
// Initialize
$getID3 = getid3_instance();
$file_realpath = backdrop_realpath($file->uri);
// Verify file exists, as external files are saved as managed files
// Ex: this prevents errors on media_youtube or media_vimeo entries.
if (file_exists($file_realpath)) {
// Analyze.
return $getID3->analyze($file_realpath);
}
return NULL;
}
/**
* Implements hook_file_presave().
*/
function getid3_file_presave($file) {
// Make sure we do not try to extract ID3 data from non valid types.
if (!in_array($file->type, array('video', 'audio'))) {
return null;
}
// Load the ID3 data.
$id3_data = getid3_analyze_file($file);
// If we have data, attach it to metadata.
if ($id3_data) {
// Set the duration
if (isset($id3_data['playtime_string'])) {
$file->metadata['duration'] = $id3_data['playtime_string'];
}
// Update video specific information.
if (isset($id3_data['video'])) {
$file->metadata['width'] = $id3_data['video']['resolution_x'];
$file->metadata['height'] = $id3_data['video']['resolution_y'];
}
// Update audio specific information.
if (isset($id3_data['audio'])) {
$file->metadata['audio_format'] = $id3_data['audio']['dataformat'];
$file->metadata['audio_sample_rate'] = $id3_data['audio']['sample_rate'];
$file->metadata['audio_channel_mode'] = $id3_data['audio']['channelmode'];
$file->metadata['audio_bitrate'] = isset($id3_data['audio']['bitrate']) ? $id3_data['audio']['bitrate'] : NULL;
$file->metadata['audio_bitrate_mode'] = isset($id3_data['audio']['bitrate_mode']) ? $id3_data['audio']['bitrate_mode'] : NULL;
}
}
// @TODO: Kill off the audio module by allowing users to edit id3 tags on
// files. Explore a sub-module that allows tags to be mapped to CCK fields and
// allows reading and writing of the tags.
// Add in arbitrary ID3 tags.
if (isset($id3_data['tags_html'])) {
// We use tags_html instead of tags because it is the most reliable data
// source for pulling in non-UTF-8 characters according to getID3 docs.
foreach ($id3_data['tags_html'] as $type => $values) {
// Typically $type may be IDv2 (for MP3s) or quicktime (for AAC).
foreach ($values as $key => $value) {
$value = isset($value[0]) ? (string) $value[0] : (string) $value;
if (!empty($value) && $key != 'coverart') {
$file->metadata['tags'][$key] = html_entity_decode($value, ENT_QUOTES, 'UTF-8');
}
}
}
}
}
/**
* Triggers the batch operation for updating file entities.
*/
function getid3_perform_batch_process() {
$batch = array(
'title' => t('Updating existing File Entities with ID3 data'),
'init_message' => t('Preparing to update entities..'),
'progress_message' => t('Processed @current out of @total items.'),
'operations' => array(
array('getid3_analyze_existing_files', array()),
),
'finished' => 'getid3_perform_batch_process_complete',
);
batch_set($batch);
}
/**
* BatchAPI complete callback for getID3 import.
*/
function getid3_perform_batch_process_complete($success, $results, $operations) {
if ($success) {
backdrop_set_message(t('File entity ID3 data updated @count files successfully.', array('@count' => count($results))));
}
else {
backdrop_set_message(theme('item_list', array('items' => $results['errors'])), 'error');
}
}
/**
* Performs batch operations to update existing file entity metadata.
*
* @param $context
* @return null|string
*/
function getid3_analyze_existing_files(&$context) {
// Little workaround so update hook and can use same batch.
if (isset($context['sandbox'])) {
$sandbox = &$context['sandbox'];
}
else {
$sandbox = &$context;
}
// Lets update 10 files at a time.
if (!isset($sandbox['progress'])) {
$sandbox['progress'] = 0;
$sandbox['current_fid'] = 0;
// We only select files that are not in the getid3_meta table.
$sandbox['max'] = db_query('SELECT COUNT(fid) FROM {file_managed} f WHERE f.filemime LIKE :video OR f.filemime LIKE :audio', array(':video' => 'video%', ':audio' => 'audio%'))->fetchField();
}
$query = db_select('file_managed', 'f')
->fields('f', array('fid'))
->condition('fid', $sandbox['current_fid'], '>')
->range(0, 10)
->orderBy('fid', 'ASC');
$db_or = db_or();
$db_or->condition('f.filemime', db_like('video') . '%', 'LIKE');
$db_or->condition('f.filemime', db_like('audio') . '%', 'LIKE');
$query->condition($db_or);
$files = $query->execute()->fetchAll();
foreach ($files as $file) {
// We just need to re-save entities.
$file = file_load($file->fid);
file_save($file);
// Update batch
$sandbox['progress']++;
$context['results'][] = $file->fid;
$sandbox['current_fid'] = $file->fid;
}
$context['message'] = t('Parsing @current out of @max files', array('@current' => count($context['results']), '@max' => $sandbox['max']));
// Let Batch API or upgrade hook know if this batch set is completed.
$context['finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']);
$sandbox['#finished'] = $context['finished'];
}
/**
* Implements hook_views_api().
*/
function getid3_views_api() {
return array(
'api' => 3.0,
'path' => backdrop_get_path('module', 'getid3') . '/includes',
);
}
/**
* Format a float duration into minutes:seconds.
*
* @param $variables
* Array with 'duration' key.
*/
function theme_getid3_duration($variables) {
$duration = $variables['duration'];
$seconds = round((($duration / 60) - floor($duration / 60)) * 60);
$minutes = floor($duration / 60);
if ($seconds >= 60) {
$seconds -= 60;
$minutes++;
}
return ((int) $minutes) . ':' . str_pad($seconds, 2, 0, STR_PAD_LEFT);
}
/**
* Format an audio sample rate.
*
* @param $variables
* Array with 'sample_rate' key.
*/
function theme_getid3_sample_rate($variables) {
return t('@sampleratekHz', array('@samplerate' => (int) ($variables['sample_rate'] / 1000)));
}
/**
* Format an audio bitrate.
*
* @param $variables
* Array with 'bitrate' key.
*/
function theme_getid3_bitrate($variables) {
return t('@bitrateKbps', array('@bitrate' => (int) ($variables['bitrate'] / 1000)));
}
/**
* Implements hook_autoload_info().
*/
function getid3_autoload_info() {
return array(
'getid3_metadata_audio_bitrate' => 'includes/handlers/getid3_metadata_audio_bitrate.inc',
'getid3_metadata_audio_bitrate_mode' => 'includes/handlers/getid3_metadata_audio_bitrate_mode.inc',
'getid3_metadata_audio_channel_mode' => 'includes/handlers/getid3_metadata_audio_channel_mode.inc',
'getid3_metadata_audio_format' => 'includes/handlers/getid3_metadata_audio_format.inc',
'getid3_metadata_audio_sample_rate' => 'includes/handlers/getid3_metadata_audio_sample_rate.inc',
'getid3_metadata_duration' => 'includes/handlers/getid3_metadata_duration.inc',
'getid3_metadata_handler' => 'includes/handlers/getid3_metadata_handler.inc',
'getid3_metadata_height' => 'includes/handlers/getid3_metadata_height.inc',
'getid3_metadata_width' => 'includes/handlers/getid3_metadata_width.inc',
'getID3' => 'includes/getid3/getid3.php',
);
}