Daniel Siepmann
5838745b96
Most of the time meta data (from my source) has the season title as title. Instead use episode title with episode number.
300 lines
11 KiB
PHP
300 lines
11 KiB
PHP
<?php
|
|
|
|
namespace DanielSiepmann\Videcutting\Tests\Unit;
|
|
|
|
/*
|
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
* 02110-1301, USA.
|
|
*/
|
|
|
|
use DanielSiepmann\Videcutting\Cutting;
|
|
use DanielSiepmann\Videcutting\VideoInfo;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Prophecy\PhpUnit\ProphecyTrait;
|
|
use Symfony\Component\Process\Process;
|
|
|
|
/**
|
|
* @covers DanielSiepmann\Videcutting\Cutting
|
|
*/
|
|
class CuttingTest extends TestCase
|
|
{
|
|
use ProphecyTrait;
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function instanceCanBeCreated(): void
|
|
{
|
|
$video = $this->prophesize(VideoInfo::class);
|
|
$subject = new Cutting(
|
|
$video->reveal()
|
|
);
|
|
|
|
static::assertInstanceOf(Cutting::class, $subject);
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function generatesCommandsForCuttingWithoutAds(): void
|
|
{
|
|
$video = $this->prophesize(VideoInfo::class);
|
|
$video->getStart()->willReturn('10.05.20');
|
|
$video->getEnd()->willReturn('13.10.25');
|
|
$video->getAds()->willReturn([]);
|
|
$video->getOriginalFilename()->willReturn('Some-Video.mp4');
|
|
$video->getOriginalFilenameWithSuffix('cut-1')->willReturn('Some-Video-cut-1.mp4');
|
|
|
|
$subject = new Cutting(
|
|
$video->reveal()
|
|
);
|
|
|
|
$commands = [];
|
|
foreach ($subject->getCommandsForCutting() as $command) {
|
|
$commands[] = $command;
|
|
}
|
|
|
|
static::assertCount(1, $commands);
|
|
static::assertSame(
|
|
"ffmpeg -y -ss '10.05.20' -to '13.10.25' -i 'Some-Video.mp4' -c copy '/tmp/Some-Video-cut-1.mp4'",
|
|
$commands[0]->getCommandLine()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function generatesCommandsForCuttingWithAds(): void
|
|
{
|
|
$video = $this->prophesize(VideoInfo::class);
|
|
$video->getStart()->willReturn('1:05.20');
|
|
$video->getEnd()->willReturn('13:10.25');
|
|
$video->getAds()->willReturn([
|
|
['2:10', '3:05'],
|
|
['10:07', '11:10'],
|
|
]);
|
|
$video->getOriginalFilename()->willReturn('Some-Video.mp4');
|
|
$video->getOriginalFilenameWithSuffix('cut-1')->willReturn('Some-Video-cut-1.mp4');
|
|
$video->getOriginalFilenameWithSuffix('cut-2')->willReturn('Some-Video-cut-2.mp4');
|
|
$video->getOriginalFilenameWithSuffix('cut-3')->willReturn('Some-Video-cut-3.mp4');
|
|
|
|
$subject = new Cutting(
|
|
$video->reveal()
|
|
);
|
|
|
|
$commands = [];
|
|
foreach ($subject->getCommandsForCutting() as $command) {
|
|
$commands[] = $command;
|
|
}
|
|
|
|
static::assertCount(3, $commands, 'Did not get expected number of cutting commands');
|
|
static::assertSame(
|
|
"ffmpeg -y -ss '1:05.20' -to '2:10' -i 'Some-Video.mp4' -c copy '/tmp/Some-Video-cut-1.mp4'",
|
|
$commands[0]->getCommandLine()
|
|
);
|
|
static::assertSame(
|
|
"ffmpeg -y -ss '3:05' -to '10:07' -i 'Some-Video.mp4' -c copy '/tmp/Some-Video-cut-2.mp4'",
|
|
$commands[1]->getCommandLine()
|
|
);
|
|
static::assertSame(
|
|
"ffmpeg -y -ss '11:10' -to '13:10.25' -i 'Some-Video.mp4' -c copy '/tmp/Some-Video-cut-3.mp4'",
|
|
$commands[2]->getCommandLine()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function generatesCommandForGeneratingMetadata(): void
|
|
{
|
|
$video = $this->prophesize(VideoInfo::class);
|
|
$video->getOriginalFilename()->willReturn('Some-Video.mp4');
|
|
$video->getOriginalFilenameWithSuffix('metadata')->willReturn('Some-Video-metadata.mp4');
|
|
|
|
$subject = new Cutting(
|
|
$video->reveal()
|
|
);
|
|
|
|
$command = $subject->getCommandForGeneratingMetadata();
|
|
|
|
static::assertSame(
|
|
"ffmpeg -y -i 'Some-Video.mp4' -f ffmetadata '/tmp/Some-Video-metadata.txt'",
|
|
$command->getCommandLine()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function throwsExceptionForGeneratingConcatInputFileIfNoConcatIsAvailable(): void
|
|
{
|
|
$video = $this->prophesize(VideoInfo::class);
|
|
|
|
$subject = new Cutting(
|
|
$video->reveal()
|
|
);
|
|
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
$this->expectExceptionMessage('No temp files for concat available. Did you call "getCommandsForCutting()" before?');
|
|
$this->expectExceptionCode(1601455216);
|
|
|
|
$subject->getCommandForGeneratingConcatInputFile();
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function generatesCommandsForGeneratingConcatInputFileWithNoAds(): void
|
|
{
|
|
$video = $this->prophesize(VideoInfo::class);
|
|
$video->getStart()->willReturn('10.05.20');
|
|
$video->getEnd()->willReturn('13.10.25');
|
|
$video->getAds()->willReturn([]);
|
|
$video->getOriginalFilename()->willReturn('Some-Video.mp4');
|
|
$video->getOriginalFilenameWithSuffix('cut-1')->willReturn('Some-Video-cut-1.mp4');
|
|
$video->getOriginalFilenameWithSuffix('concat')->willReturn('Some-Video-concat.mp4');
|
|
|
|
$subject = new Cutting(
|
|
$video->reveal()
|
|
);
|
|
|
|
foreach ($subject->getCommandsForCutting() as $command) {
|
|
// Just generate all commands to have proper internal state
|
|
}
|
|
|
|
$command = $subject->getCommandForGeneratingConcatInputFile();
|
|
|
|
static::assertSame(
|
|
"printf 'file /tmp/Some-Video-cut-1.mp4' > /tmp/Some-Video-concat.txt",
|
|
$command->getCommandLine()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function generatesCommandsForGeneratingConcatInputFileWithAds(): void
|
|
{
|
|
$video = $this->prophesize(VideoInfo::class);
|
|
$video->getStart()->willReturn('10.05.20');
|
|
$video->getEnd()->willReturn('13.10.25');
|
|
$video->getAds()->willReturn([
|
|
['2:10', '3:05'],
|
|
['10:07', '11:10'],
|
|
]);
|
|
$video->getOriginalFilename()->willReturn('Some-Video.mp4');
|
|
$video->getOriginalFilenameWithSuffix('cut-1')->willReturn('Some-Video-cut-1.mp4');
|
|
$video->getOriginalFilenameWithSuffix('cut-2')->willReturn('Some-Video-cut-2.mp4');
|
|
$video->getOriginalFilenameWithSuffix('cut-3')->willReturn('Some-Video-cut-3.mp4');
|
|
$video->getOriginalFilenameWithSuffix('concat')->willReturn('Some-Video-concat.mp4');
|
|
|
|
$subject = new Cutting(
|
|
$video->reveal()
|
|
);
|
|
|
|
foreach ($subject->getCommandsForCutting() as $command) {
|
|
// Just generate all commands to have proper internal state
|
|
}
|
|
|
|
$command = $subject->getCommandForGeneratingConcatInputFile();
|
|
|
|
static::assertSame(
|
|
'printf \'file /tmp/Some-Video-cut-1.mp4\nfile /tmp/Some-Video-cut-2.mp4\nfile /tmp/Some-Video-cut-3.mp4\''
|
|
. ' > /tmp/Some-Video-concat.txt',
|
|
$command->getCommandLine()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function generatesCommandForGeneratingVideoWithCustomTitle(): void
|
|
{
|
|
$video = $this->prophesize(VideoInfo::class);
|
|
$video->getTargetFilePath()->willReturn('Series-Name/Series-01/10-episode title.mp4');
|
|
$video->getOriginalFilenameWithSuffix('concat')->willReturn('Series-Name_Series-01_episode-title-01-concat.mp4');
|
|
$video->getOriginalFilenameWithSuffix('metadata')->willReturn('Series-Name_Series-01_episode-title-01-metadata.mp4');
|
|
$video->getTitleForHumans()->willReturn('01 - Episode Title');
|
|
|
|
$subject = new Cutting(
|
|
$video->reveal()
|
|
);
|
|
|
|
$command = $subject->getCommandForGeneratingVideo();
|
|
|
|
static::assertSame(
|
|
'ffmpeg -y -f concat -safe 0 -i \'/tmp/Series-Name_Series-01_episode-title-01-concat.txt\' -c copy'
|
|
. ' -f ffmetadata -i \'/tmp/Series-Name_Series-01_episode-title-01-metadata.txt\' -c copy -map_metadata 1'
|
|
. ' -metadata Title=\'01 - Episode Title\''
|
|
. ' \'Series-Name/Series-01/10-episode title.mp4\'',
|
|
$command->getCommandLine()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function generatesCommandForCleanup(): void
|
|
{
|
|
$video = $this->prophesize(VideoInfo::class);
|
|
$video->getTargetFilePath()->willReturn('Series-Name/Series-01/10-episode title.mp4');
|
|
$video->getOriginalFilenameWithSuffix('concat')->willReturn('Series-Name_Series-01_episode-title-01-concat.mp4');
|
|
$video->getOriginalFilenameWithSuffix('metadata')->willReturn('Series-Name_Series-01_episode-title-01-metadata.mp4');
|
|
|
|
$subject = new Cutting(
|
|
$video->reveal()
|
|
);
|
|
|
|
$command = $subject->getCommandForCleanup();
|
|
|
|
static::assertSame(
|
|
'rm \'/tmp/Series-Name_Series-01_episode-title-01-concat.txt\' \'/tmp/Series-Name_Series-01_episode-title-01-metadata.txt\'',
|
|
$command->getCommandLine()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function generatesCommandForCleanupWithSingleTempFile(): void
|
|
{
|
|
$video = $this->prophesize(VideoInfo::class);
|
|
$video->getStart()->willReturn('10.05.20');
|
|
$video->getEnd()->willReturn('13.10.25');
|
|
$video->getAds()->willReturn([]);
|
|
$video->getOriginalFilename()->willReturn('Some-Video.mp4');
|
|
$video->getTargetFilePath()->willReturn('Series-Name/Series-01/10-episode title.mp4');
|
|
$video->getOriginalFilenameWithSuffix('cut-1')->willReturn('Some-Video-cut-1.mp4');
|
|
$video->getOriginalFilenameWithSuffix('concat')->willReturn('Series-Name_Series-01_episode-title-01-concat.mp4');
|
|
$video->getOriginalFilenameWithSuffix('metadata')->willReturn('Series-Name_Series-01_episode-title-01-metadata.mp4');
|
|
|
|
$subject = new Cutting(
|
|
$video->reveal()
|
|
);
|
|
|
|
foreach ($subject->getCommandsForCutting() as $command) {
|
|
// Just generate all commands to have proper internal state
|
|
}
|
|
|
|
$command = $subject->getCommandForCleanup();
|
|
|
|
static::assertSame(
|
|
'rm \'/tmp/Some-Video-cut-1.mp4\' \'/tmp/Series-Name_Series-01_episode-title-01-concat.txt\' \'/tmp/Series-Name_Series-01_episode-title-01-metadata.txt\'',
|
|
$command->getCommandLine()
|
|
);
|
|
}
|
|
}
|