koel/app/Services/Streamers/TranscodingStreamer.php

67 lines
1.8 KiB
PHP
Raw Normal View History

2016-01-28 15:19:06 +00:00
<?php
2017-04-20 11:20:32 +00:00
namespace App\Services\Streamers;
2016-01-28 15:19:06 +00:00
use App\Models\Song;
2016-02-02 08:01:47 +00:00
class TranscodingStreamer extends Streamer implements StreamerInterface
2016-01-28 15:19:06 +00:00
{
/**
2016-08-03 10:42:11 +00:00
* Bit rate the stream should be transcoded at.
*
* @var int
*/
2016-08-03 10:42:11 +00:00
private $bitRate;
/**
* Time point to start transcoding from.
*
* @var int
*/
private $startTime;
2016-08-03 10:42:11 +00:00
public function __construct(Song $song, $bitRate, $startTime = 0)
2016-01-28 15:19:06 +00:00
{
parent::__construct($song);
2016-08-03 10:42:11 +00:00
$this->bitRate = $bitRate;
$this->startTime = $startTime;
2016-01-28 15:19:06 +00:00
}
/**
* On-the-fly stream the current song while transcoding.
*/
public function stream()
{
$ffmpeg = config('koel.streaming.ffmpeg_path');
2016-06-10 07:33:27 +00:00
abort_unless(is_executable($ffmpeg), 500, 'Transcoding requires valid ffmpeg settings.');
2016-01-28 15:19:06 +00:00
2016-08-03 10:42:11 +00:00
$bitRate = filter_var($this->bitRate, FILTER_SANITIZE_NUMBER_INT);
2016-01-28 15:19:06 +00:00
// Since we can't really know the content length of a file while it's still being transcoded,
// "calculating" it (like below) will be much likely to result in net::ERR_CONTENT_LENGTH_MISMATCH errors.
// Better comment these for now.
2016-01-31 14:00:15 +00:00
//
2016-01-28 15:19:06 +00:00
// header('Accept-Ranges: bytes');
// $bytes = round(($this->song->length * $bitRate * 1024) / 8);
// header("Content-Length: $bytes");
header('Content-Type: audio/mpeg');
header('Content-Disposition: attachment; filename="'.basename($this->song->path).'"');
$args = [
'-i '.escapeshellarg($this->song->path),
'-map 0:0',
'-v 0',
"-ab {$bitRate}k",
'-f mp3',
'-',
];
if ($this->startTime) {
array_unshift($args, "-ss {$this->startTime}");
}
2016-01-28 15:19:06 +00:00
passthru("$ffmpeg ".implode($args, ' '));
}
}