1
|
|
|
<?php |
2
|
|
|
namespace Divergence\Models\Media; |
3
|
|
|
|
4
|
|
|
use Exception; |
5
|
|
|
|
6
|
|
|
class Audio extends Media |
7
|
|
|
{ |
8
|
|
|
// configurables |
9
|
|
|
public static $previewExtractCommand = 'ffmpeg -i %1$s -ss %3$u -t %4$u -f mp3 -y %2$s'; // 1=input file, 2=output file, 3=start time, 4=duration |
10
|
|
|
public static $previewDuration = 30; |
11
|
|
|
public static $iconPath = '/site-root/img/icons/filetypes/mp3.png'; |
12
|
|
|
|
13
|
|
|
|
14
|
|
|
// magic methods |
15
|
|
|
public static function __classLoaded() |
16
|
|
|
{ |
17
|
|
|
$className = get_called_class(); |
18
|
|
|
|
19
|
|
|
Media::$mimeHandlers['audio/mpeg'] = $className; |
20
|
|
|
|
21
|
|
|
parent::__classLoaded(); |
|
|
|
|
22
|
|
|
} |
23
|
|
|
|
24
|
|
|
|
25
|
|
|
public function getValue($name) |
26
|
|
|
{ |
27
|
|
|
switch ($name) { |
28
|
|
|
case 'ThumbnailMIMEType': |
29
|
|
|
return 'image/png'; |
30
|
|
|
|
31
|
|
|
case 'Width': |
32
|
|
|
return 128; |
33
|
|
|
|
34
|
|
|
case 'Height': |
35
|
|
|
return 128; |
36
|
|
|
|
37
|
|
|
case 'Extension': |
38
|
|
|
|
39
|
|
|
switch ($this->MIMEType) { |
40
|
|
|
case 'audio/mpeg': |
41
|
|
|
return 'mp3'; |
42
|
|
|
default: |
43
|
|
|
throw new Exception('Unable to find audio extension for mime-type: '.$this->MIMEType); |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
// no break |
47
|
|
|
default: |
48
|
|
|
return parent::getValue($name); |
49
|
|
|
} |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
|
53
|
|
|
// public methods |
54
|
|
|
public static function getBlankPath($contextClass) |
55
|
|
|
{ |
56
|
|
|
$node = Site::resolvePath(static::$iconPath); |
|
|
|
|
57
|
|
|
return $node ? $node->RealPath : null; |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
public function getImage($sourceFile = null) |
61
|
|
|
{ |
62
|
|
|
if (!isset($sourceFile)) { |
63
|
|
|
$sourceFile = $this->BlankPath; |
|
|
|
|
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
return imagecreatefromstring(file_get_contents($sourceFile)); |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
public function createPreview() |
70
|
|
|
{ |
71
|
|
|
// check if a preview already exists |
72
|
|
|
|
73
|
|
|
if (!empty($_REQUEST['startTime']) && is_numeric($_REQUEST['startTime']) && ($_REQUEST['startTime'] >= 0) && ($_REQUEST['startTime'] < $this->Duration)) { |
74
|
|
|
$startTime = $_REQUEST['startTime']; |
75
|
|
|
} else { |
76
|
|
|
$startTime = 0; |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
$previewPath = tempnam('/tmp', 'mediaPreview'); |
80
|
|
|
|
81
|
|
|
// generate preview |
82
|
|
|
$cmd = sprintf(static::$previewExtractCommand, $this->FilesystemPath, $previewPath, $startTime, static::$previewDuration); |
|
|
|
|
83
|
|
|
shell_exec($cmd); |
84
|
|
|
|
85
|
|
|
if (!filesize($previewPath)) { |
86
|
|
|
throw new Exception('Preview output is empty'); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
// create media instance |
90
|
|
|
$PreviewMedia = Media::createFromFile($previewPath, [ |
91
|
|
|
'ContextClass' => 'Media' |
92
|
|
|
,'ContextID' => $this->ID |
93
|
|
|
,'Caption' => sprintf('%u sec preview (%us-%us)', static::$previewDuration, $startTime, $startTime+static::$previewDuration), |
94
|
|
|
]); |
95
|
|
|
|
96
|
|
|
return $PreviewMedia; |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
// static methods |
100
|
|
|
# public static function analyzeFile($filename, $mediaInfo = array()) |
101
|
|
|
# { |
102
|
|
|
# // Initialize getID3 engine |
103
|
|
|
# $getID3 = new getID3(); |
104
|
|
|
# |
105
|
|
|
# $mediaInfo['id3Info'] = $getID3->analyze($filename); |
106
|
|
|
# |
107
|
|
|
# $mediaInfo['width'] = 0; |
108
|
|
|
# $mediaInfo['height'] = 0; |
109
|
|
|
# $mediaInfo['duration'] = $mediaInfo['id3Info']['playtime_seconds']; |
110
|
|
|
# |
111
|
|
|
# return $mediaInfo; |
112
|
|
|
# } |
113
|
|
|
} |
114
|
|
|
|