File Coverage

blib/lib/Video/Generator.pm
Criterion Covered Total %
statement 63 83 75.9
branch 4 20 20.0
condition n/a
subroutine 14 15 93.3
pod 2 2 100.0
total 83 120 69.1


line stmt bran cond sub pod time code
1             package Video::Generator;
2              
3 3     3   158044 use strict;
  3         20  
  3         87  
4 3     3   16 use warnings;
  3         6  
  3         83  
5              
6 3     3   1469 use Class::Utils qw(set_params);
  3         73608  
  3         62  
7 3     3   215 use Error::Pure qw(err);
  3         7  
  3         114  
8 3     3   1622 use FFmpeg::Command;
  3         145529  
  3         24  
9 3     3   150 use File::Path qw(rmtree);
  3         17  
  3         219  
10 3     3   1571 use File::Spec::Functions qw(catfile);
  3         2671  
  3         204  
11 3     3   2382 use File::Temp qw(tempdir);
  3         38885  
  3         204  
12 3     3   1493 use IO::CaptureOutput qw(capture_exec);
  3         5953  
  3         155  
13 3     3   1434 use Image::Random;
  3         117579  
  3         109  
14 3     3   29 use Readonly;
  3         7  
  3         147  
15 3     3   1781 use Video::Delay::Const;
  3         693  
  3         89  
16 3     3   1477 use Video::Pattern;
  3         5514  
  3         1808  
17              
18             # Constants.
19             Readonly::Scalar our $SPACE => q{ };
20              
21             our $VERSION = 0.09;
22              
23             # Constructor.
24             sub new {
25 9     9 1 21600 my ($class, @params) = @_;
26              
27             # Create object.
28 9         25 my $self = bless {}, $class;
29              
30             # Delay generator.
31 9         30 $self->{'delay_generator'} = undef;
32              
33             # Duration.
34 9         19 $self->{'duration'} = 10000;
35              
36             # Frames per second.
37 9         16 $self->{'fps'} = 60;
38              
39             # FFmpeg pixel format.
40 9         15 $self->{'ffmpeg_pixel_format'} = undef;
41              
42             # FFmpeg video codec.
43 9         17 $self->{'ffmpeg_video_codec'} = undef;
44              
45             # Image generator.
46 9         15 $self->{'image_generator'} = undef;
47              
48             # Image type.
49 9         17 $self->{'image_type'} = 'bmp';
50              
51             # Temporary dir.
52 9         25 $self->{'temp_dir'} = undef;
53              
54             # Verbose mode.
55 9         18 $self->{'verbose'} = 0;
56              
57             # Video pattern generator.
58 9         17 $self->{'video_pattern'} = undef;
59              
60             # Sizes.
61 9         14 $self->{'height'} = 1080;
62 9         16 $self->{'width'} = 1920;
63              
64             # Process params.
65 9         33 set_params($self, @params);
66              
67             # Temporary directory.
68 7 50       96 if (! defined $self->{'temp_dir'}) {
69 7         22 $self->{'temp_dir'} = tempdir();
70             }
71              
72             # Image generator.
73 7 50       2485 if (! defined $self->{'image_generator'}) {
74             $self->{'image_generator'} = Image::Random->new(
75             'height' => $self->{'height'},
76             'type' => $self->{'image_type'},
77 7         40 'width' => $self->{'width'},
78             );
79             }
80              
81             # Delay generator.
82 6 50       14445 if (! defined $self->{'delay_generator'}) {
83 6         29 $self->{'delay_generator'} = Video::Delay::Const->new(
84             'const' => 1000,
85             );
86             }
87              
88             # Video pattern generator.
89 6 50       157 if (! defined $self->{'video_pattern'}) {
90             $self->{'video_pattern'} = Video::Pattern->new(
91             'delay_generator' => $self->{'delay_generator'},
92             'duration' => $self->{'duration'},
93             'fps' => $self->{'fps'},
94 6         25 'image_generator' => $self->{'image_generator'},
95             );
96             }
97              
98             # Object.
99 1         95 return $self;
100             }
101              
102             # Create random video.
103             sub create {
104 0     0 1   my ($self, $out_path) = @_;
105              
106             # Create images.
107 0           $self->{'video_pattern'}->create($self->{'temp_dir'});
108 0 0         if ($self->{'verbose'}) {
109 0           print "Video pattern generator created images for video in ".
110             "temporary directory.\n";
111             }
112              
113             # Create video.
114 0           my $ffmpeg = FFmpeg::Command->new;
115             my $images_path = catfile($self->{'temp_dir'},
116 0           '%03d.'.$self->{'image_type'});
117             my @command_options = ('-loglevel', 'error', '-r', $self->{'fps'},
118             '-i', $images_path,
119             $self->{'ffmpeg_video_codec'}
120             ? ('-c:v', $self->{'ffmpeg_video_codec'})
121             : (),
122             $self->{'ffmpeg_pixel_format'}
123 0 0         ? ('-pix_fmt', $self->{'ffmpeg_pixel_format'})
    0          
124             :(),
125             '-pix_fmt', 'yuv420p',
126             $out_path);
127 0           $ffmpeg->options(@command_options);
128 0           $ffmpeg->exec;
129 0 0         if ($ffmpeg->stderr) {
130 0           my @stderr = split m/\n/ms, $ffmpeg->stderr;
131 0           my $command = join $SPACE, @command_options;
132             err "Error with command 'ffmpeg $command'.",
133 0           map { ('STDERR', $_) } @stderr;
  0            
134             }
135 0 0         if ($self->{'verbose'}) {
136 0           print "Created video file.\n";
137             }
138              
139             # Remove temporary directory.
140 0           rmtree $self->{'temp_dir'};
141 0 0         if ($self->{'verbose'}) {
142 0           print "Removed temporary directory.\n";
143             }
144              
145 0           return;
146             }
147              
148             1;
149              
150             __END__