mirror of
https://github.com/koel/koel
synced 2025-02-16 05:18:37 +00:00
Add FLAC support
This commit is contained in:
parent
20157e489e
commit
65fb45f08a
5 changed files with 168 additions and 48 deletions
16
.env.example
16
.env.example
|
@ -13,6 +13,7 @@ APP_KEY=
|
|||
# Another random 32-char string
|
||||
JWT_SECRET=
|
||||
|
||||
|
||||
# Username and password for the initial admin account
|
||||
# This info will be populated into the database during `php artisan db:seed`
|
||||
# After that, it can (and should) be removed from this .env file
|
||||
|
@ -20,12 +21,15 @@ ADMIN_EMAIL=
|
|||
ADMIN_NAME=
|
||||
ADMIN_PASSWORD=
|
||||
|
||||
|
||||
# The maximum scan time, in seconds. Increase this if you have a huge library.
|
||||
APP_MAX_SCAN_TIME=600
|
||||
|
||||
|
||||
# The streaming method.
|
||||
# Can be either 'php' (default), 'x-sendfile', or 'x-accel-redirect'
|
||||
# See https://github.com/phanan/koel/wiki#streaming-music for more information.
|
||||
# Note: This setting doesn't have effect if the media needs transcoding (e.g. FLAC).
|
||||
STREAMING_METHOD=php
|
||||
|
||||
|
||||
|
@ -33,11 +37,23 @@ STREAMING_METHOD=php
|
|||
LASTFM_API_KEY=
|
||||
LASTFM_API_SECRET=
|
||||
|
||||
|
||||
# You can also configure Koel to use a CDN to serve the media files.
|
||||
# This url must be mapped to the home URL of your Koel's installation.
|
||||
# No trailing slash, please.
|
||||
CDN_URL=
|
||||
|
||||
|
||||
# If you want to transcode FLAC to MP3 and stream it on the fly, make sure the
|
||||
# settings here are sane.
|
||||
# The full path of ffmpeg binary. Make sure it's executable by the web user.
|
||||
FFMPEG_PATH=/usr/local/bin/ffmpeg
|
||||
|
||||
# The bit rate of the out mp3 stream. Higher value results in better quality,
|
||||
# but bigger file and more bandwidth.
|
||||
OUTPUT_BIT_RATE=128
|
||||
|
||||
|
||||
# The variables below are Laravel-specific.
|
||||
# You can change them if you know what you're doing. Otherwise, just leave them as-is.
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace App\Http\Controllers\API;
|
|||
use App\Http\Streamers\PHPStreamer;
|
||||
use App\Http\Streamers\XAccelRedirectStreamer;
|
||||
use App\Http\Streamers\XSendFileStreamer;
|
||||
use App\Http\Streamers\TranscodingStreamer;
|
||||
use App\Models\Song;
|
||||
|
||||
class SongController extends Controller
|
||||
|
@ -18,6 +19,10 @@ class SongController extends Controller
|
|||
*/
|
||||
public function play(Song $song)
|
||||
{
|
||||
if (ends_with(mime_content_type($song->path), 'flac')) {
|
||||
return (new TranscodingStreamer($song))->stream();
|
||||
}
|
||||
|
||||
switch (env('STREAMING_METHOD')) {
|
||||
case 'x-sendfile':
|
||||
return (new XSendFileStreamer($song))->stream();
|
||||
|
|
49
app/Http/Streamers/TranscodingStreamer.php
Normal file
49
app/Http/Streamers/TranscodingStreamer.php
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Streamers;
|
||||
|
||||
use App\Models\Song;
|
||||
|
||||
class TranscodingStreamer extends BaseStreamer implements StreamerInterface
|
||||
{
|
||||
public function __construct(Song $song)
|
||||
{
|
||||
parent::__construct($song);
|
||||
}
|
||||
|
||||
/**
|
||||
* On-the-fly stream the current song while transcoding.
|
||||
*/
|
||||
public function stream()
|
||||
{
|
||||
if (!is_executable($ffmpeg = env('FFMPEG_PATH', '/usr/local/bin/ffmpeg'))) {
|
||||
abort(500, 'Transcoding requires valid ffmpeg settings.');
|
||||
}
|
||||
|
||||
$bitRate = filter_var(env('OUTPUT_BIT_RATE', 128), FILTER_SANITIZE_NUMBER_INT);
|
||||
|
||||
// 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.
|
||||
//
|
||||
// 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',
|
||||
'-',
|
||||
];
|
||||
|
||||
passthru("$ffmpeg ".implode($args, ' '));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -46,7 +46,7 @@ class Media
|
|||
'ugly' => [], // Unmodified files
|
||||
];
|
||||
|
||||
$files = Finder::create()->files()->name('/\.(mp3|ogg|m4a)$/i')->in($path);
|
||||
$files = Finder::create()->files()->name('/\.(mp3|ogg|m4a|flac)$/i')->in($path);
|
||||
|
||||
foreach ($files as $file) {
|
||||
$song = $this->syncFile($file);
|
||||
|
|
144
composer.lock
generated
144
composer.lock
generated
|
@ -4,8 +4,8 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "73595742c708c946629155b84a000a62",
|
||||
"content-hash": "b4898021e96521543995ae80b2a17399",
|
||||
"hash": "ed1a234d6513d5a7614be084578c3bd7",
|
||||
"content-hash": "af504fd25aa5ea944786ee8288568758",
|
||||
"packages": [
|
||||
{
|
||||
"name": "barryvdh/laravel-ide-helper",
|
||||
|
@ -70,6 +70,54 @@
|
|||
],
|
||||
"time": "2015-12-21 19:48:06"
|
||||
},
|
||||
{
|
||||
"name": "captbaritone/transcode-to-mp3-stream",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/captbaritone/transcode-to-mp3-stream.git",
|
||||
"reference": "ad66ccad3a86d6ada4158f59a6e179eb359b89b7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/captbaritone/transcode-to-mp3-stream/zipball/ad66ccad3a86d6ada4158f59a6e179eb359b89b7",
|
||||
"reference": "ad66ccad3a86d6ada4158f59a6e179eb359b89b7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "dev-master"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Captbaritone\\TranscodeToMp3Stream": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jordan Eldredge",
|
||||
"email": "jordanEldredge@gmail.com",
|
||||
"homepage": "http://jordaneldredge.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Transcode various audio formats to mp3 streams on the fly",
|
||||
"homepage": "http://github.com/captbaritone/transcode-to-mp3-stream",
|
||||
"keywords": [
|
||||
"audio",
|
||||
"mp3",
|
||||
"stream",
|
||||
"transcode"
|
||||
],
|
||||
"time": "2016-01-25 15:31:23"
|
||||
},
|
||||
{
|
||||
"name": "classpreloader/classpreloader",
|
||||
"version": "3.0.0",
|
||||
|
@ -339,16 +387,16 @@
|
|||
},
|
||||
{
|
||||
"name": "guzzlehttp/psr7",
|
||||
"version": "1.2.1",
|
||||
"version": "1.2.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/psr7.git",
|
||||
"reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982"
|
||||
"reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/4d0bdbe1206df7440219ce14c972aa57cc5e4982",
|
||||
"reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/f5d04bdd2881ac89abde1fb78cc234bce24327bb",
|
||||
"reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -393,7 +441,7 @@
|
|||
"stream",
|
||||
"uri"
|
||||
],
|
||||
"time": "2015-11-03 01:34:55"
|
||||
"time": "2016-01-23 01:23:02"
|
||||
},
|
||||
{
|
||||
"name": "jakub-onderka/php-console-color",
|
||||
|
@ -578,16 +626,16 @@
|
|||
},
|
||||
{
|
||||
"name": "laravel/framework",
|
||||
"version": "v5.2.6",
|
||||
"version": "v5.2.12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/framework.git",
|
||||
"reference": "b774c304ee81fcf5402fa06b261b364ba8f29cf0"
|
||||
"reference": "6b6255ad7bfbdb721b8d00b09d52b146c5d363d7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/b774c304ee81fcf5402fa06b261b364ba8f29cf0",
|
||||
"reference": "b774c304ee81fcf5402fa06b261b364ba8f29cf0",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/6b6255ad7bfbdb721b8d00b09d52b146c5d363d7",
|
||||
"reference": "6b6255ad7bfbdb721b8d00b09d52b146c5d363d7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -702,7 +750,7 @@
|
|||
"framework",
|
||||
"laravel"
|
||||
],
|
||||
"time": "2015-12-31 17:41:58"
|
||||
"time": "2016-01-26 04:15:37"
|
||||
},
|
||||
{
|
||||
"name": "league/flysystem",
|
||||
|
@ -867,23 +915,23 @@
|
|||
},
|
||||
{
|
||||
"name": "mtdowling/cron-expression",
|
||||
"version": "v1.0.4",
|
||||
"version": "v1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mtdowling/cron-expression.git",
|
||||
"reference": "fd92e883195e5dfa77720b1868cf084b08be4412"
|
||||
"reference": "c9ee7886f5a12902b225a1a12f36bb45f9ab89e5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/mtdowling/cron-expression/zipball/fd92e883195e5dfa77720b1868cf084b08be4412",
|
||||
"reference": "fd92e883195e5dfa77720b1868cf084b08be4412",
|
||||
"url": "https://api.github.com/repos/mtdowling/cron-expression/zipball/c9ee7886f5a12902b225a1a12f36bb45f9ab89e5",
|
||||
"reference": "c9ee7886f5a12902b225a1a12f36bb45f9ab89e5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.*"
|
||||
"phpunit/phpunit": "~4.0|~5.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
|
@ -907,7 +955,7 @@
|
|||
"cron",
|
||||
"schedule"
|
||||
],
|
||||
"time": "2015-01-11 23:07:46"
|
||||
"time": "2016-01-26 21:23:30"
|
||||
},
|
||||
{
|
||||
"name": "namshi/jose",
|
||||
|
@ -1059,16 +1107,16 @@
|
|||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
"version": "1.1.4",
|
||||
"version": "1.1.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/random_compat.git",
|
||||
"reference": "d762ee5b099a29044603cd4649851e81aa66cb47"
|
||||
"reference": "dd8998b7c846f6909f4e7a5f67fabebfc412a4f7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/d762ee5b099a29044603cd4649851e81aa66cb47",
|
||||
"reference": "d762ee5b099a29044603cd4649851e81aa66cb47",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/dd8998b7c846f6909f4e7a5f67fabebfc412a4f7",
|
||||
"reference": "dd8998b7c846f6909f4e7a5f67fabebfc412a4f7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1103,7 +1151,7 @@
|
|||
"pseudorandom",
|
||||
"random"
|
||||
],
|
||||
"time": "2015-12-10 14:48:13"
|
||||
"time": "2016-01-06 13:31:20"
|
||||
},
|
||||
{
|
||||
"name": "phanan/cascading-config",
|
||||
|
@ -1514,16 +1562,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/class-loader",
|
||||
"version": "v2.8.1",
|
||||
"version": "v2.8.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/class-loader.git",
|
||||
"reference": "ec74b0a279cf3a9bd36172b3e3061591d380ce6c"
|
||||
"reference": "98e9089a428ed0e39423b67352c57ef5910a3269"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/class-loader/zipball/ec74b0a279cf3a9bd36172b3e3061591d380ce6c",
|
||||
"reference": "ec74b0a279cf3a9bd36172b3e3061591d380ce6c",
|
||||
"url": "https://api.github.com/repos/symfony/class-loader/zipball/98e9089a428ed0e39423b67352c57ef5910a3269",
|
||||
"reference": "98e9089a428ed0e39423b67352c57ef5910a3269",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1562,7 +1610,7 @@
|
|||
],
|
||||
"description": "Symfony ClassLoader Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-12-05 17:37:59"
|
||||
"time": "2016-01-03 15:33:41"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
|
@ -1926,16 +1974,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.0.1",
|
||||
"version": "v1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "49ff736bd5d41f45240cec77b44967d76e0c3d25"
|
||||
"reference": "1289d16209491b584839022f29257ad859b8532d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/49ff736bd5d41f45240cec77b44967d76e0c3d25",
|
||||
"reference": "49ff736bd5d41f45240cec77b44967d76e0c3d25",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d",
|
||||
"reference": "1289d16209491b584839022f29257ad859b8532d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1947,7 +1995,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
"dev-master": "1.1-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
@ -1981,20 +2029,20 @@
|
|||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2015-11-20 09:19:13"
|
||||
"time": "2016-01-20 09:13:37"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php56",
|
||||
"version": "v1.0.1",
|
||||
"version": "v1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php56.git",
|
||||
"reference": "e2e77609a9e2328eb370fbb0e0d8b2000ebb488f"
|
||||
"reference": "4d891fff050101a53a4caabb03277284942d1ad9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/e2e77609a9e2328eb370fbb0e0d8b2000ebb488f",
|
||||
"reference": "e2e77609a9e2328eb370fbb0e0d8b2000ebb488f",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/4d891fff050101a53a4caabb03277284942d1ad9",
|
||||
"reference": "4d891fff050101a53a4caabb03277284942d1ad9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2004,7 +2052,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
"dev-master": "1.1-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
@ -2037,20 +2085,20 @@
|
|||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2015-12-18 15:10:25"
|
||||
"time": "2016-01-20 09:13:37"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-util",
|
||||
"version": "v1.0.1",
|
||||
"version": "v1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-util.git",
|
||||
"reference": "4271c55cbc0a77b2641f861b978123e46b3da969"
|
||||
"reference": "8de62801aa12bc4dfcf85eef5d21981ae7bb3cc4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-util/zipball/4271c55cbc0a77b2641f861b978123e46b3da969",
|
||||
"reference": "4271c55cbc0a77b2641f861b978123e46b3da969",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-util/zipball/8de62801aa12bc4dfcf85eef5d21981ae7bb3cc4",
|
||||
"reference": "8de62801aa12bc4dfcf85eef5d21981ae7bb3cc4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2059,7 +2107,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
"dev-master": "1.1-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
@ -2089,7 +2137,7 @@
|
|||
"polyfill",
|
||||
"shim"
|
||||
],
|
||||
"time": "2015-11-04 20:28:58"
|
||||
"time": "2016-01-20 09:13:37"
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
|
@ -3745,7 +3793,9 @@
|
|||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"stability-flags": {
|
||||
"captbaritone/transcode-to-mp3-stream": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
|
|
Loading…
Add table
Reference in a new issue