diff options
author | Paul Arthur <flowerysong00@yahoo.com> | 2011-04-08 23:15:33 -0400 |
---|---|---|
committer | Paul Arthur <flowerysong00@yahoo.com> | 2011-04-08 23:26:21 -0400 |
commit | f7c1e57cf021f1d6f00b209f1640bc24c6303391 (patch) | |
tree | 31d8cbd7c1672e4121d29f659819c4d46baaeaed /lib | |
parent | 4aa256cb07ee2dd0a113b56b06accf1dae2c61c7 (diff) | |
download | ampache-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.php | 34 | ||||
-rw-r--r-- | lib/class/stream.class.php | 114 | ||||
-rw-r--r-- | lib/ui.lib.php | 3 |
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; |