phpvideotoolkit-v2 icon indicating copy to clipboard operation
phpvideotoolkit-v2 copied to clipboard

Uncaught exception 'PHPVideoToolkit\\Exception' with message 'The command "-y" has already been given and it cannot be repeated.

Open alphanull opened this issue 11 years ago • 6 comments

Setup is the same as with issue #39, but this time with V2.1.5:

$video = new PHPVideoToolkit\Video($tmpName);
$output_format = new PHPVideoToolkit\VideoFormat_Mp4();
$video->save($name.".mp4", $output_format);

So, is this a bug or just me doing something wrong?

alphanull avatar Dec 04 '14 20:12 alphanull

Using the bleeding edge version I cannot repeat this.

Can you replace your code with this... and then copy and paste the stacktrace?

try
{
    $video = new PHPVideoToolkit\Video($tmpName);
    $output_format = new PHPVideoToolkit\VideoFormat_Mp4();
    $process = $video->save($name.".mp4", $output_format);
}
catch(PHPVideoToolkit\FfmpegProcessOutputException $e)
{
    echo '<h1>Error</h1>';
    PHPVideoToolkit\Trace::vars($e->getMessage());
    echo '<h2>Exception</h2>';
    PHPVideoToolkit\Trace::vars($e);

    $process = $video->getProcess();
    if($process->isCompleted())
    {
        echo '<hr /><h2>Executed Command</h2>';
        PHPVideoToolkit\Trace::vars($process->getExecutedCommand());
        echo '<hr /><h2>FFmpeg Process Messages</h2>';
        PHPVideoToolkit\Trace::vars($process->getMessages());
        echo '<hr /><h2>Buffer Output</h2>';
        PHPVideoToolkit\Trace::vars($process->getBuffer(true));
    }
}
catch(PHPVideoToolkit\Exception $e)
{
    echo '<h1>Error</h1>';
    PHPVideoToolkit\Trace::vars($e->getMessage());
    echo '<h2>Exception</h2>';
    PHPVideoToolkit\Trace::vars($e);
}
catch(Exception $e)
{
    echo '<h1>Error</h1>';
    PHPVideoToolkit\Trace::vars($e->getMessage());
    echo '<h2>Exception</h2>';
    PHPVideoToolkit\Trace::vars($e);
}

buggedcom avatar Dec 05 '14 13:12 buggedcom

Hi,

I think I know now what actually happened. Turned out it was not the command I thought, but actually another command I used before. Here is a more complete code example:

$video = new PHPVideoToolkit\Video($tmpName, $videoConfig);
// create poster image
$video -> extractFrame(new PHPVideoToolkit\Timecode(10)) -> save($name.".jpg", null, \PHPVideoToolkit\Media::OVERWRITE_EXISTING);
// create X.264
$output_format = new PHPVideoToolkit\VideoFormat_Mp4("output", $videoConfig);
$output_format ->setVideoBitrate("800k")
               ->setAudioBitrate("128k")
               ->setH264Profile("baseline")
               ->setThreads(12);
$process = $video->getProcess();
$process->addCommand('-vf', 'scale=720:trunc(ow/a/2)*2');
$video->save($name.".mp4", $output_format, \PHPVideoToolkit\Media::OVERWRITE_EXISTING);

So I declared a Video Class once and do several things with it.

But what happens is that commands seem to be repeated. So, if I use extractFrame and tell it to overwrite the existing file, it adds a "-y" command to ffmpeg. So far so good.

But when I save the same video again, but with a different format and also ask to overwrite existing files, the "-y" command is also added again, resulting in the exception. The same thing seems to happen with other stuff, for example if I set another output format (using the "New" declarator) on the same video objekt, all commands are not cleared, but just carried over.

So yeah, bug or user error? I am not sure, but at least I did not expect this behavior.

My interim solution is to redeclare the video object before each operation:

$video = new PHPVideoToolkit\Video($tmpName, $videoConfig);
// create poster image
$video -> extractFrame(new PHPVideoToolkit\Timecode(10)) -> save($name.".jpg", null, \PHPVideoToolkit\Media::OVERWRITE_EXISTING);
// create X.264
$video = new PHPVideoToolkit\Video($tmpName, $videoConfig);
$output_format = new PHPVideoToolkit\VideoFormat_Mp4("output", $videoConfig);
$output_format ->setVideoBitrate("800k")
               ->setAudioBitrate("128k")
               ->setH264Profile("baseline")
               ->setThreads(12);
$process = $video->getProcess();
$process->addCommand('-vf', 'scale=720:trunc(ow/a/2)*2');
$video->save($name.".mp4", $output_format, \PHPVideoToolkit\Media::OVERWRITE_EXISTING);

Now, the error is gone. But is this really the way it was meant to work?

alphanull avatar Dec 05 '14 14:12 alphanull

No, the -y override should be wiped upon save if not needed, so definitely a bug. I'm about to have a sauna and a cider for Friday evening, but after that I will make a fix.

buggedcom avatar Dec 05 '14 14:12 buggedcom

Well, take your time and have fun with your sauna ;) At least I have a workaround for the meantime.

PS: what I also saw is that the "-ss" command from the frame extraction was carried over too, so it appeared also with the following "save()". It did not trigger the "duplicate" error here (since it was not specified in the folowing "save()"), but also resulted in an unwanted result. Just FYI.

alphanull avatar Dec 05 '14 15:12 alphanull

I've added the fix for -y, however the issue raised by re-using the Video or (Image or Audio) instances is rather tricky because we can't simply wipe the commands or process object after a save because if an error occurs then information is needed. Whilst we could detect successful encodes it raises further problems when involving progress handlers.

I could in theory create a reset function that could be manually called to reset all the previous commands issued, however we then run into an issue of determining which commands should be expected to be reset by default and which should not.

Any further thoughts on the matter would be appreciated as creating a reset is probably tricker than your solution of just initialising a new video object.

buggedcom avatar Dec 08 '14 10:12 buggedcom

OK, I understand the problem. Hmmm. OK, what about this: for example after each save, all commands and settings are cleared, so they are not carried over to the next operation (which I think is pretty unintuitive). But this information is still being kept, in a kind of buffer. Maybe even several sessions in an array, so you could have something like a command / communication / error history.

alphanull avatar Dec 12 '14 17:12 alphanull