* * 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 -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 generatesCommandForGeneratingVideo(): 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->getCommandForGeneratingVideo(); static::assertSame( 'ffmpeg -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="$episodeTitle"' . ' \'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() ); } }