laravel-ffmpeg icon indicating copy to clipboard operation
laravel-ffmpeg copied to clipboard

DynamicHLSPlaylist parseLines always return null

Open sandyh90 opened this issue 3 years ago • 4 comments

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);
    }

sandyh90 avatar Nov 09 '22 02:11 sandyh90

Please post your code that involve DynamicHLSPlaylist class. Maybe this solve https://github.com/protonemedia/laravel-ffmpeg/pull/466

SadeghPM avatar Jan 28 '23 07:01 SadeghPM

@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 avatar Jan 28 '23 07:01 sandyh90

@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 avatar Feb 01 '23 01:02 aronquiray

@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

sandyh90 avatar Feb 01 '23 19:02 sandyh90