webPath = $webPath;
}
public function isAudioViewable($extension) {
global $config;
if (empty($extension) || trim($extension) === '') {
return false;
}
$extension = strtolower($extension);
if (!in_array($extension, $this->allowedAudioExtensions)) {
return false;
}
$settingKey = getExtensionSetting($extension, 'viewing');
if ($settingKey !== null) {
return isset($config['viewable_files'][$settingKey]) ?
$config['viewable_files'][$settingKey] : false;
}
return false;
}
public function renderAudioPlayer($fullPath, $filename, $extension, $currentPath) {
global $router, $config;
$pathParts = explode('/', trim($currentPath, '/'));
$lastPart = end($pathParts);
if ($lastPart === $filename) {
array_pop($pathParts);
$currentPath = implode('/', $pathParts);
}
$this->serveAudioView($fullPath, $filename, $extension, $currentPath);
exit;
}
private function serveAudioView($fullPath, $filename, $extension, $currentPath) {
global $router, $config, $iconType;
$fileSize = filesize($fullPath);
$fileSizeFormatted = $this->formatBytes($fileSize);
$fileModified = date('Y-m-d H:i:s', filemtime($fullPath));
$audioInfo = $this->getAudioInfo($fullPath, $extension);
$downloadUrl = $router->generateFileURL($currentPath, $filename, 'download');
$viewUrl = $router->generateFileURL($currentPath, $filename, 'view', 'default');
$originalRawUrl = $router->generateFileURL($currentPath, $filename, 'view', 'raw');
$audioDisplayUrl = $originalRawUrl;
$currentFullUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$backUrl = preg_replace('/\/[^\/]+\/\?.*$/', '/', $currentFullUrl);
if (!preg_match('/\?/', $currentFullUrl)) {
$backUrl = preg_replace('/\/[^\/]+\/$/', '/', $currentFullUrl);
}
$securityStatus = getSecurityStatus();
$lockIcon = $securityStatus['secure']
? $this->webPath . '/.indexer_files/icons/app/green.png'
: $this->webPath . '/.indexer_files/icons/app/red.png';
$mimeType = $this->getAudioMimeType($extension);
$canPlayNatively = $this->canPlayInBrowser($extension);
$displayTitle = $audioInfo['title'] ?: $filename;
$displayArtist = $audioInfo['artist'];
$hasCoverArt = !empty($audioInfo['cover_art']);
$audioIconPath = getIconPath('file', $extension);
$useIcon = ($iconType !== 'disabled');
$useEmoji = ($iconType === 'emoji' || $audioIconPath === null);
$iconSrc = $audioIconPath;
?>
This audio format () may not be natively supported by your browser.
Please download the file or try opening it in a compatible media player.
🎵
Filename:
Title:
Artist:
Album:
Year:
Genre:
Type:
Audio
Duration:
Bitrate:
Sample Rate:
Channels:
File Size:
Modified:
'audio/mpeg',
'wav' => 'audio/wav',
'aac' => 'audio/aac',
'flac' => 'audio/flac',
'm4a' => 'audio/mp4',
'ogg' => 'audio/ogg',
'oga' => 'audio/ogg',
'opus' => 'audio/ogg',
];
return $mimeTypes[$extension] ?? 'audio/mpeg';
}
private function canPlayInBrowser($extension) {
$nativelySupported = ['mp3', 'wav', 'ogg', 'oga', 'opus', 'm4a', 'aac', 'flac'];
if (in_array($extension, $nativelySupported)) {
return true;
}
return false;
}
private function getAudioInfo($fullPath, $extension) {
$info = [
'title' => null,
'artist' => null,
'album' => null,
'year' => null,
'genre' => null,
'duration' => null,
'bitrate' => null,
'sample_rate' => null,
'channels' => null,
'cover_art' => null
];
$getID3Path = dirname(__FILE__) . '/getid3/getid3.php';
if (!file_exists($getID3Path)) {
return $info;
}
require_once($getID3Path);
try {
$getID3 = new getID3;
$fileInfo = $getID3->analyze($fullPath);
if (isset($fileInfo['tags'])) {
foreach (['id3v2', 'id3v1', 'vorbiscomment', 'quicktime', 'riff', 'asf'] as $tagFormat) {
if (isset($fileInfo['tags'][$tagFormat])) {
$tags = $fileInfo['tags'][$tagFormat];
if (!$info['title'] && isset($tags['title'][0])) {
$info['title'] = $tags['title'][0];
}
if (!$info['artist'] && isset($tags['artist'][0])) {
$info['artist'] = $tags['artist'][0];
}
if (!$info['album'] && isset($tags['album'][0])) {
$info['album'] = $tags['album'][0];
}
if (!$info['year'] && isset($tags['year'][0])) {
$info['year'] = $tags['year'][0];
}
if (!$info['genre'] && isset($tags['genre'][0])) {
$info['genre'] = $tags['genre'][0];
}
}
}
}
if (isset($fileInfo['playtime_seconds'])) {
$seconds = round($fileInfo['playtime_seconds']);
$minutes = floor($seconds / 60);
$seconds = $seconds % 60;
$info['duration'] = sprintf('%d:%02d', $minutes, $seconds);
}
if (isset($fileInfo['audio']['bitrate'])) {
$bitrate = round($fileInfo['audio']['bitrate'] / 1000);
$info['bitrate'] = $bitrate . ' kbps';
}
if (isset($fileInfo['audio']['sample_rate'])) {
$sampleRate = round($fileInfo['audio']['sample_rate'] / 1000, 1);
$info['sample_rate'] = $sampleRate . ' kHz';
}
if (isset($fileInfo['audio']['channels'])) {
$channels = $fileInfo['audio']['channels'];
if ($channels == 1) {
$info['channels'] = 'Mono';
} elseif ($channels == 2) {
$info['channels'] = 'Stereo';
} else {
$info['channels'] = $channels . ' channels';
}
}
if (isset($fileInfo['comments']['picture'][0])) {
$picture = $fileInfo['comments']['picture'][0];
if (isset($picture['data'])) {
$imageData = $picture['data'];
$imageMime = isset($picture['image_mime']) ? $picture['image_mime'] : 'image/jpeg';
$info['cover_art'] = 'data:' . $imageMime . ';base64,' . base64_encode($imageData);
}
}
} catch (Exception $e) {
}
return $info;
}
private function formatBytes($size) {
if ($size === null) return '-';
$units = ['B', 'KB', 'MB', 'GB'];
for ($i = 0; $size > 1024 && $i < count($units) - 1; $i++) {
$size /= 1024;
}
return round($size, 2) . ' ' . $units[$i];
}
}
?>