uploading works, but AV info is not automatically detected and video activation featu...
[living-lab-site.git] / application / helpers / video_helper.php
1 <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2
3 /**
4  * Tests if parameter is a resolution string with format [width]x[height].
5  * @param string $res
6  * @return boolean
7  */
8 function is_res($res)
9 {
10         if (strpos($res, 'x') === FALSE)
11         return FALSE;
12
13         return TRUE;
14 }
15
16 /**
17  * Return the width from a resolution string with format [width]x[height].
18  * @param string $res
19  */
20 function res_to_width($res)
21 {
22         if (! is_res($res))
23         return FALSE;
24
25         return intval( substr($res, 0, strpos($res, 'x')) );
26 }
27
28 /**
29 * Return the height from a resolution string with format [width]x[height].
30 * @param string $res
31 */
32 function res_to_height($res)
33 {
34         if (! is_res($res))
35         return FALSE;
36
37         return intval( substr($res, strpos($res, 'x') + 1) );
38 }
39
40 /**
41  * Compares two resolution strings $a and $b with format [width]x[height] based
42  * on theirs megapixels number by return -1, 0 or 1 like any compare function.
43  * @param string $a
44  * @param string $b
45  * @param function $access_function     filters input parameters by doing something
46  * like $a = $access_function($a). Leave it NULL for no filtering.
47  */
48 function megapixels_cmp($a, $b, $access_function = NULL)
49 {
50         if ($access_function !== NULL)
51         {
52                 $a = $access_function($a);
53                 $b = $access_function($b);
54         }
55
56         $a_w = intval( substr($a, 0, strpos($a, 'x')) );
57         $a_h = intval( substr($a, strpos($a, 'x') + 1) );
58         if ($a_w === FALSE || $a_h === FALSE)
59         return 0;
60         $a_Mp = $a_w * $a_h;
61         $b_w = intval( substr($b, 0, strpos($b, 'x')) );
62         $b_h = intval( substr($b, strpos($b, 'x') + 1) );
63         if ($b_w === FALSE || $b_h === FALSE)
64         return 0;
65         $b_Mp = $b_w * $b_h;
66
67         if ($a_Mp == $b_Mp)
68         return 0;
69
70         return $a_Mp > $b_Mp ? 1 : -1;
71 }
72
73 /**
74  * Return the index of the $haystack element which has the closest resolution
75  * to $needle resolution string.
76  * @param array $haystack
77  * @param string $needle
78  * @param function $access_function     filters input parameters by doing something
79  * like $a = $access_function($a). Leave it NULL for no filtering.
80  */
81 function get_closest_res($haystack, $needle, $access_function = NULL)
82 {
83         $d_min = INF;
84         $i_min = FALSE;
85
86         foreach($haystack as $i => $elem)
87         {
88                 if ($access_function !== NULL)
89                 $elem = $access_function($elem);
90
91                 $d = abs(res_to_width($elem) * res_to_height($elem)
92                 - res_to_width($needle) * res_to_height($needle));
93                 if ($d < $d_min)
94                 {
95                         $d_min = $d;
96                         $i_min = $i;
97                 }
98         }
99
100         return $i_min;
101 }
102
103 /**
104  * Returns information about an Audio/Video file.
105  * 
106  * @param string $file_name Audio/Video file
107  * @return dictionary a dictionary of audio/video properties with keys:
108  * <ul>
109  *   <li>width</li>
110  *   <li>height</li>
111  *   <li>dar (display aspect ratio)</li>
112  *   <li>duration (formated as [HH:]mm:ss)</li>
113  *   <li>size (in bytes)</li>
114  * </ul>
115  */
116 function get_av_info($file_name)
117 {
118         // TODO use ffprobe to return width, height, DAR, duration and size of a video
119         
120         return array('width'=> 1440, 'height'=> 1080, 'dar'=> '16:9',
121                         'duration'=> '00:10', 'size'=> 5568748);
122 }
123
124 /**
125  * Return a dictionary with formats compliant for DB and CIS and computes
126  * resolutions such that an uploaded video will not be converted to a higher
127  * resolution.
128  * 
129  * @param type $formats formats as in content_ingestion config file
130  * @param type $av_info structure as returned by get_av_info function from this
131  * helper
132  * @param type $elim_dupl_res eliminate consecutive formats with the same
133  * resolution
134  * @return array a dictionary with DB format at key 'db_formats' and CIS format
135  * at key 'transcode_configs' 
136  */
137 function prepare_formats($formats, $av_info, $elim_dupl_res=FALSE)
138 {
139         $transcode_configs = array();
140         $db_formats = array();
141         
142         for ($i = 0; $i < count($formats); $i++)
143         {
144                 $transcode_configs[$i]['container'] = $formats[$i]['container'];
145                 $transcode_configs[$i]['extension'] = $formats[$i]['extension'];
146                 $db_formats[$i]['ext'] = $formats[$i]['extension'];
147                 $transcode_configs[$i]['a_codec'] = $formats[$i]['audio_codec'];
148                 $transcode_configs[$i]['a_bitrate'] = $formats[$i]['audio_bit_rate'];
149                 $transcode_configs[$i]['a_samplingrate'] = $formats[$i]['audio_sampling_rate'];
150                 $transcode_configs[$i]['a_channels'] = $formats[$i]['audio_channels'];
151                 $transcode_configs[$i]['v_codec'] = $formats[$i]['video_codec'];
152                 $transcode_configs[$i]['v_bitrate'] = $formats[$i]['video_bit_rate'];
153                 $transcode_configs[$i]['v_framerate'] = $formats[$i]['video_frame_rate'];
154                 $transcode_configs[$i]['v_dar'] = $av_info['dar'];
155                 $db_formats[$i]['dar'] = $av_info['dar'];
156
157                 $sar = $av_info['width'] / $av_info['height'];
158                 
159                 if ($av_info['height'] < $formats[$i]['video_height'])
160                 {
161                         $width = $av_info['width'];
162                         $height = $av_info['height'];
163                 }
164                 else
165                 {
166                         $height = $formats[$i]['video_height'];
167                         $width = round($sar * $height);
168                 }
169                 
170                 $transcode_configs[$i]['v_resolution'] = "${width}x${height}";
171                 $db_formats[$i]['res'] = "${width}x${height}";
172         }
173         
174         // Eliminate formats with duplicate resolutions.
175         if ($elim_dupl_res)
176         {
177                 for ($i = 1; $i < count($transcode_configs); $i++)
178                 {
179                         if ($transcode_configs[$i]['v_resolution']
180                                         === $transcode_configs[$i - 1]['v_resolution'])
181                         {
182                                 unset($transcode_configs[$i - 1]);
183                                 unset($db_formats[$i - 1]);
184                                 $i--;
185                         }
186                 }
187         }
188         
189         return array('transcode_configs'=>$transcode_configs,
190                 'db_formats'=>$db_formats);
191 }
192
193 /* End of file video_helper.php */
194 /* Location: ./application/helpers/video_helper.php */