summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPaul Arthur <flowerysong00@yahoo.com>2011-04-08 23:15:33 -0400
committerPaul Arthur <flowerysong00@yahoo.com>2011-04-08 23:26:21 -0400
commitf7c1e57cf021f1d6f00b209f1640bc24c6303391 (patch)
tree31d8cbd7c1672e4121d29f659819c4d46baaeaed /lib
parent4aa256cb07ee2dd0a113b56b06accf1dae2c61c7 (diff)
downloadampache-f7c1e57cf021f1d6f00b209f1640bc24c6303391.tar.gz
ampache-f7c1e57cf021f1d6f00b209f1640bc24c6303391.tar.bz2
ampache-f7c1e57cf021f1d6f00b209f1640bc24c6303391.zip
Transcoding/streaming cleanup.
Derive our new filesize from the length, not the previous bitrate and size. Allow higher bitrates than the source when they're different formats. Return HTTP error codes when an error occurs. Minor cleanup.
Diffstat (limited to 'lib')
-rw-r--r--lib/class/song.class.php34
-rw-r--r--lib/class/stream.class.php114
-rw-r--r--lib/ui.lib.php3
3 files changed, 83 insertions, 68 deletions
diff --git a/lib/class/song.class.php b/lib/class/song.class.php
index b6899267..1d5329a0 100644
--- a/lib/class/song.class.php
+++ b/lib/class/song.class.php
@@ -63,7 +63,10 @@ class Song extends database_object implements media {
/* Setting Variables */
public $_transcoded = false;
+ public $resampled = false;
public $_fake = false; // If this is a 'construct_from_array' object
+ public $transcoded_from;
+ private $_transcode_cmd;
/**
* Constructor
@@ -970,10 +973,20 @@ class Song extends database_object implements media {
$conf_var = 'transcode_' . $this->type;
$conf_type = 'transcode_' . $this->type . '_target';
+ $conf_cmd = 'transcode_cmd_' . $this->type;
if (Config::get($conf_var)) {
$this->_transcoded = true;
- debug_event('auto_transcode','Transcoding to ' . $this->type,'5');
+ $this->_transcoded_from = $this->type;
+ $this->_transcode_cmd = Config::get($conf_cmd);
+
+ $this->format_type(Config::get($conf_type));
+ if ($this->type == $this->_transcoded_from) {
+ $this->_resampled = true;
+ }
+
+ debug_event('transcode', 'Transcoding from ' .
+ $this->_transcoded_from . ' to ' . $this->type, 5);
return false;
}
@@ -983,26 +996,17 @@ class Song extends database_object implements media {
/**
* stream_cmd
+ *
* test if the song type streams natively and
* if not returns a transcoding command from the config
- * we can't use this->type because its been formated for the
- * downsampling
*/
public function stream_cmd() {
- // Find the target for this transcode
- $conf_type = 'transcode_' . $this->type . '_target';
- $stream_cmd = 'transcode_cmd_' . $this->type;
- $this->format_type(Config::get($conf_type));
-
- if (Config::get($stream_cmd)) {
- return $stream_cmd;
+ if ($this->native_stream()) {
+ return null;
}
- else {
- debug_event('Downsample','Error: Transcode ' . $stream_cmd . ' for ' . $this->type . ' not found, using downsample','2');
- }
-
- return false;
+
+ return $this->_transcode_cmd;
} // end stream_cmd
diff --git a/lib/class/stream.class.php b/lib/class/stream.class.php
index f9ba484f..c64b3a2e 100644
--- a/lib/class/stream.class.php
+++ b/lib/class/stream.class.php
@@ -602,14 +602,17 @@ class Stream {
} // create_ram
/**
- * start_downsample
- * This is a rather complext function that starts the downsampling of a song and returns the
- * opened file handled a reference to the song object is passed so that the changes we make
- * in here affect the external object, References++
+ * start_transcode
+ *
+ * This is a rather complex function that starts the transcoding or
+ * resampling of a song and returns the opened file handle. A reference
+ * to the song object is passed so that the changes we make in here
+ * affect the external object, References++
*/
- public static function start_downsample(&$song,$now_playing_id=0,$song_name=0,$start=0) {
+ public static function start_transcode(&$song, $song_name = 0, $start = 0) {
- /* Check to see if bitrates are set if so let's go ahead and optomize! */
+ // Check to see if bitrates are set.
+ // If so let's go ahead and optimize!
$max_bitrate = Config::get('max_bit_rate');
$min_bitrate = Config::get('min_bit_rate');
$time = time();
@@ -629,33 +632,33 @@ class Stream {
$db_results = Dba::read($sql);
$results = Dba::fetch_row($db_results);
- // Current number of active streams (current is already in now playing, worst case make it 1)
+ // Current number of active streams (current is already
+ // in now playing, worst case make it 1)
$active_streams = intval($results[0]);
if (!$active_streams) { $active_streams = '1'; }
+ debug_event('transcode', "Active streams: $active_streams", 5);
- /* If only one user, they'll get all available. Otherwise split up equally. */
- $sample_rate = floor($max_bitrate/$active_streams);
+ // If only one user, they'll get all available.
+ // Otherwise split up equally.
+ $sample_rate = floor($max_bitrate / $active_streams);
- /* If min_bitrate is set, then we'll exit if the bandwidth would need to be split up smaller than the min. */
- if ($min_bitrate > 1 AND ($max_bitrate/$active_streams) < $min_bitrate) {
-
- /* Log the failure */
- debug_event('downsample',"Error: Max bandwidith already allocated. $active_streams Active Streams",'2');
- echo "Maximum bandwidth already allocated. Try again later.";
+ // If min_bitrate is set, then we'll exit if the
+ // bandwidth would need to be lower.
+ if ($min_bitrate > 1 AND ($max_bitrate / $active_streams) < $min_bitrate) {
+ debug_event('transcode', "Max bandwidth already allocated. Active streams: $active_streams", 2);
+ header('HTTP/1.1 503 Service Temporarily Unavailable');
exit();
-
}
else {
- $sample_rate = floor($max_bitrate/$active_streams);
+ $sample_rate = floor($max_bitrate / $active_streams);
} // end else
- // Never go over the users sample rate
+ // Never go over the user's sample rate
if ($sample_rate > $user_sample_rate) { $sample_rate = $user_sample_rate; }
- debug_event('downsample',"Downsampled: $active_streams current active streams, downsampling to $sample_rate",'2');
+ debug_event('transcode', "Downsampling to $sample_rate", 5);
} // end if we've got bitrates
-
else {
$sample_rate = $user_sample_rate;
}
@@ -663,57 +666,64 @@ class Stream {
/* Validate the bitrate */
$sample_rate = self::validate_bitrate($sample_rate);
- /* Never Upsample a song */
- if (($sample_rate*1000) > $song->bitrate) {
- $sample_rate = self::validate_bitrate($song->bitrate/1000);
- $sample_ratio = '1';
- }
- else {
- /* Set the Sample Ratio */
- $sample_ratio = $sample_rate/($song->bitrate/1000);
+ // Never upsample a song
+ if ($song->resampled && ($sample_rate * 1000) > $song->bitrate) {
+ $sample_rate = self::validate_bitrate($song->bitrate / 1000);
}
- // Set the new size for the song
- $song->size = floor($sample_ratio*$song->size);
+ // Set the new size for the song (in bytes)
+ $song->size = floor($sample_rate * $song->time * 125);
/* Get Offset */
- $offset = ( $start*$song->time )/( $song->size );
- $offsetmm = floor($offset/60);
- $offsetss = floor($offset-$offsetmm*60);
+ $offset = ($start * $song->time) / $song->size;
+ $offsetmm = floor($offset / 60);
+ $offsetss = floor($offset - ($offsetmm * 60));
// If flac then format it slightly differently
- if ($song->type == 'flac') {
- $offset = sprintf("%02d:%02d",$offsetmm,$offsetss);
+ // HACK
+ if ($song->transcoded_from == 'flac') {
+ $offset = sprintf('%02d:%02d', $offsetmm, $offsetss);
}
else {
- $offset = sprintf("%02d.%02d",$offsetmm,$offsetss);
+ $offset = sprintf('%02d.%02d', $offsetmm, $offsetss);
}
/* Get EOF */
- $eofmm = floor($song->time/60);
- $eofss = floor($song->time-$eofmm*60);
- $eof = sprintf("%02d.%02d",$eofmm,$eofss);
+ $eofmm = floor($song->time / 60);
+ $eofss = floor($song->time - ($eofmm * 60));
+ $eof = sprintf('%02d.%02d', $eofmm, $eofss);
$song_file = escapeshellarg($song->file);
- /* Replace Variables */
- $downsample_command = Config::get($song->stream_cmd());
- $downsample_command = str_replace("%FILE%",$song_file,$downsample_command,$file_exists);
- $downsample_command = str_replace("%OFFSET%",$offset,$downsample_command,$offset_exists);
- $downsample_command = str_replace("%EOF%",$eof,$downsample_command,$eof_exists);
- $downsample_command = str_replace("%SAMPLE%",$sample_rate,$downsample_command,$sample_exists);
+ $transcode_command = $song->stream_cmd();
+ if ($transcode_command == null) {
+ debug_event('downsample', 'song->stream_cmd() returned null', 2);
+ return null;
+ }
- if (!$file_exists || !$offset_exists || !$eof_exists || !$sample_exists) {
- debug_event('downsample', 'Warning: Downsample command missing a variable; values are File:' . $file_exists . ' Offset:' . $offset_exists . ' Eof:' . $eof_exists . ' Sample:' . $sample_exists, '1');
+ $string_map = array(
+ '%FILE%' => $song_file,
+ '%OFFSET%' => $offset,
+ '%OFFSET_MM%' => $offsetmm,
+ '%OFFSET_SS%' => $offsetss,
+ '%EOF%' => $eof,
+ '%EOF_MM%' => $eofmm,
+ '%EOF_SS%' => $eofss,
+ '%SAMPLE%' => $sample_rate
+ );
+
+ foreach ($string_map as $search => $replace) {
+ $transcode_command = str_replace($search, $replace, $transcode_command, $ret);
+ if (!$ret) {
+ debug_event('downsample', "$search not in downsample command", 5);
+ }
}
- // If we are debugging log this event
- $message = "Start Downsample using CMD: $downsample_command";
- debug_event('downsample',$message,'3');
+ debug_event('downsample', "Downsample command: $transcode_command", 3);
- $fp = popen($downsample_command, 'rb');
+ $fp = popen($transcode_command, 'rb');
// Return our new handle
- return ($fp);
+ return $fp;
} // start_downsample
diff --git a/lib/ui.lib.php b/lib/ui.lib.php
index c7d21741..ded371a1 100644
--- a/lib/ui.lib.php
+++ b/lib/ui.lib.php
@@ -103,10 +103,11 @@ if (!function_exists('ngettext')) {
* access_denied
* Throws an error if they try to do something that they aren't allowed to.
*/
-function access_denied() {
+function access_denied($error = "Access Denied") {
// Clear any crap we've got up top
ob_end_clean();
+ header("HTTP/1.1 403 $error");
require_once Config::get('prefix') . '/templates/show_denied.inc.php';
exit;