laravel-ffmpeg
laravel-ffmpeg copied to clipboard
DynamicHLSPlaylist parseLines always return null
Hi,
I have a problem while starting to encode my video using this package because DynamicHLSPlaylist::parseLines() value always return null did i do something wrong?
and this is my code and debug output.
Code
$withoutFileExt = preg_replace('/\\.[^.\\s]{3,4}$/', '', $getVideoData->video_file);
$format = new X264('aac', 'libx264');
$format->setAdditionalParameters(['-c:v', 'h264_amf']);
$lowBitrate = ($format)->setKiloBitrate(250);
$midBitrate = ($format)->setKiloBitrate(500);
$highBitrate = ($format)->setKiloBitrate(1000);
FFMpeg::fromDisk('public')
->open("video/{$getVideoData->folder_video}/{$getVideoData->video_file}")
->exportForHLS()
->addFormat($lowBitrate)
->addFormat($midBitrate)
->addFormat($highBitrate)
->save("{$withoutFileExt}.m3u8");
Output
TypeError: ProtoneMedia\LaravelFFMpeg\Http\DynamicHLSPlaylist::parseLines(): Argument #1 ($lines) must be of type string, null given, called in D:\Server\VideoEncoder\vendor\pbmedia\laravel-ffmpeg\src\Exporters\HLSPlaylistGenerator.php on line 30 and defined in D:\Server\VideoEncoder\vendor\pbmedia\laravel-ffmpeg\src\Http\DynamicHLSPlaylist.php:157
Stack trace:
#0 D:\Server\VideoEncoder\vendor\pbmedia\laravel-ffmpeg\src\Exporters\HLSPlaylistGenerator.php(30): ProtoneMedia\LaravelFFMpeg\Http\DynamicHLSPlaylist::parseLines(NULL)
#1 D:\Server\VideoEncoder\vendor\pbmedia\laravel-ffmpeg\src\Exporters\HLSPlaylistGenerator.php(47): ProtoneMedia\LaravelFFMpeg\Exporters\HLSPlaylistGenerator->getStreamInfoLine(Object(ProtoneMedia\LaravelFFMpeg\Filesystem\Media), '0')
#2 [internal function]: ProtoneMedia\LaravelFFMpeg\Exporters\HLSPlaylistGenerator->ProtoneMedia\LaravelFFMpeg\Exporters\{closure}(Object(ProtoneMedia\LaravelFFMpeg\Filesystem\Media), 0)
#3 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Collections\Arr.php(560): array_map(Object(Closure), Array, Array)
#4 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Collections\Collection.php(719): Illuminate\Support\Arr::map(Array, Object(Closure))
#5 D:\Server\VideoEncoder\vendor\pbmedia\laravel-ffmpeg\src\Exporters\HLSPlaylistGenerator.php(57): Illuminate\Support\Collection->map(Object(Closure))
#6 D:\Server\VideoEncoder\vendor\pbmedia\laravel-ffmpeg\src\Exporters\HLSExporter.php(309): ProtoneMedia\LaravelFFMpeg\Exporters\HLSPlaylistGenerator->get(Array, Object(ProtoneMedia\LaravelFFMpeg\Drivers\PHPFFMpeg))
#7 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Collections\Traits\EnumeratesValues.php(715): ProtoneMedia\LaravelFFMpeg\Exporters\HLSExporter->ProtoneMedia\LaravelFFMpeg\Exporters\{closure}(Object(Illuminate\Support\Collection))
#8 D:\Server\VideoEncoder\vendor\pbmedia\laravel-ffmpeg\src\Exporters\HLSExporter.php(320): Illuminate\Support\Collection->pipe(Object(Closure))
#9 D:\Server\VideoEncoder\app\Jobs\TranscodingVideoData.php(67): ProtoneMedia\LaravelFFMpeg\Exporters\HLSExporter->save('mediaData/b6fea...')
#10 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php(36): App\Jobs\TranscodingVideoData->handle()
#11 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Container\Util.php(41): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#12 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php(93): Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
#13 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php(37): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#14 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Container\Container.php(651): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#15 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Bus\Dispatcher.php(128): Illuminate\Container\Container->call(Array)
#16 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(141): Illuminate\Bus\Dispatcher->Illuminate\Bus\{closure}(Object(App\Jobs\TranscodingVideoData))
#17 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(116): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(App\Jobs\TranscodingVideoData))
#18 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Bus\Dispatcher.php(132): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#19 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Queue\CallQueuedHandler.php(124): Illuminate\Bus\Dispatcher->dispatchNow(Object(App\Jobs\TranscodingVideoData), false)
#20 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(141): Illuminate\Queue\CallQueuedHandler->Illuminate\Queue\{closure}(Object(App\Jobs\TranscodingVideoData))
#21 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(116): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(App\Jobs\TranscodingVideoData))
#22 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Queue\CallQueuedHandler.php(126): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#23 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Queue\CallQueuedHandler.php(70): Illuminate\Queue\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\Queue\Jobs\DatabaseJob), Object(App\Jobs\TranscodingVideoData))
#24 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Queue\Jobs\Job.php(98): Illuminate\Queue\CallQueuedHandler->call(Object(Illuminate\Queue\Jobs\DatabaseJob), Array)
#25 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Queue\Worker.php(425): Illuminate\Queue\Jobs\Job->fire()
#26 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Queue\Worker.php(375): Illuminate\Queue\Worker->process('database', Object(Illuminate\Queue\Jobs\DatabaseJob), Object(Illuminate\Queue\WorkerOptions))
#27 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Queue\Worker.php(173): Illuminate\Queue\Worker->runJob(Object(Illuminate\Queue\Jobs\DatabaseJob), 'database', Object(Illuminate\Queue\WorkerOptions))
#28 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Queue\Console\WorkCommand.php(150): Illuminate\Queue\Worker->daemon('database', 'transcode-video', Object(Illuminate\Queue\WorkerOptions))
#29 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Queue\Console\WorkCommand.php(134): Illuminate\Queue\Console\WorkCommand->runWorker('database', 'transcode-video')
#30 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php(36): Illuminate\Queue\Console\WorkCommand->handle()
#31 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Container\Util.php(41): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#32 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php(93): Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
#33 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php(37): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#34 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Container\Container.php(651): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#35 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Console\Command.php(144): Illuminate\Container\Container->call(Array)
#36 D:\Server\VideoEncoder\vendor\symfony\console\Command\Command.php(291): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#37 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Console\Command.php(126): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#38 D:\Server\VideoEncoder\vendor\symfony\console\Application.php(1014): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#39 D:\Server\VideoEncoder\vendor\symfony\console\Application.php(301): Symfony\Component\Console\Application->doRunCommand(Object(Illuminate\Queue\Console\WorkCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#40 D:\Server\VideoEncoder\vendor\symfony\console\Application.php(171): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#41 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Console\Application.php(102): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#42 D:\Server\VideoEncoder\vendor\laravel\framework\src\Illuminate\Foundation\Console\Kernel.php(155): Illuminate\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#43 D:\Server\VideoEncoder\artisan(37): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#44 {main}
while i trace the error where caught in this method
private function getStreamInfoLine(Media $segmentPlaylistMedia, string $key): string
{
$segmentPlaylist = $segmentPlaylistMedia->getDisk()->get(
$segmentPlaylistMedia->getDirectory() . HLSExporter::generateTemporarySegmentPlaylistFilename($key)
);
$lines = DynamicHLSPlaylist::parseLines($segmentPlaylist)->filter();
return $lines->get($lines->search($segmentPlaylistMedia->getFilename()) - 1);
}
Please post your code that involve DynamicHLSPlaylist class.
Maybe this solve https://github.com/protonemedia/laravel-ffmpeg/pull/466
@SadeghPM i don't have any other code that involve with DynamicHLSPlaylist class only this basic code have relation with that class.
$withoutFileExt = preg_replace('/\\.[^.\\s]{3,4}$/', '', $getVideoData->video_file);
$format = new X264('aac', 'libx264');
$format->setAdditionalParameters(['-c:v', 'h264_amf']);
$lowBitrate = ($format)->setKiloBitrate(250);
$midBitrate = ($format)->setKiloBitrate(500);
$highBitrate = ($format)->setKiloBitrate(1000);
FFMpeg::fromDisk('public')
->open("video/{$getVideoData->folder_video}/{$getVideoData->video_file}")
->exportForHLS()
->addFormat($lowBitrate)
->addFormat($midBitrate)
->addFormat($highBitrate)
->save("{$withoutFileExt}.m3u8");
Ok I will try your pull request code hopefully it will work normally, thanks for letting me know.
@sandyh90 make sure the the video is residing in your storage folder
if you're using local, it's on
storage/app/public/video/{$getVideoData->folder_video}/{$getVideoData->video_file}
make sure that it's existing there.
if not, then try to run the command php artisan storage:link as I can see you're using the public key
Nothing is wrong with the current setup
$storageLocation = $this->isLocalStorage ? 'public/'.$location : $location;
$toLocation = $this->isLocalStorage ? "public/temp/collections/$track->uuid/".$track->uuid.'.m3u8' : "collections/$track->uuid/$track->uuid.m3u8";
$low = (new X264)->setAudioKiloBitrate(96);
$med = (new X264)->setAudioKiloBitrate(128);
$high = (new X264)->setAudioKiloBitrate(256);
$ultra = (new X264)->setAudioKiloBitrate(320);
FFMpeg::fromDisk(config('filesystems.default'))
->open($storageLocation) // MP3 file
->exportForHLS()
->addFormat($low)
->addFormat($med)
->addFormat($high)
->addFormat($ultra)
->setSegmentLength(10)
->save($toLocation); //m3u8
this is what I have on my setup.
@aronquiray yup but i have tried thing others like run php artisan storage:link command and check if the folder exists or not but nothing worked it just failed to save master playlist but to save playlist for quality selector works fine without problem