source: spip-zone/_plugins_/spipmotion/trunk/inc/spipmotion_ffmpeg_infos.php @ 107194

Last change on this file since 107194 was 107194, checked in by kent1@…, 3 years ago

Eviter des preg_match_all sur de grosses chaines pour éviter de péter la mémoire

Version 1.7.2

File size: 13.4 KB
Line 
1<?php
2/**
3 * SPIPmotion
4 * Gestion de l'encodage et des métadonnées de vidéos directement dans spip
5 *
6 * Auteurs :
7 * kent1 (http://www.kent1.info - kent1@arscenic.info)
8 * 2008-2017 - Distribué sous licence GNU/GPL
9 *
10 */
11
12if (!defined('_ECRIRE_INC_VERSION')) {
13        return;
14}
15
16function inc_spipmotion_ffmpeg_infos_dist($forcer = false) {
17        $infos_codecs = ffmpeg_recuperer_infos_codecs($forcer);
18        return $infos_codecs;
19}
20
21/**
22 * Récupération des informations sur les codecs disponibles
23 */
24function ffmpeg_recuperer_infos_codecs($forcer) {
25        if ($forcer) {
26                include_spip('inc/config');
27                if (!is_dir(_DIR_CACHE.'spipmotion')) {
28                        sous_repertoire(_DIR_CACHE, 'spipmotion');
29                }
30                $chemin_fichier = _DIR_CACHE.'spipmotion/ffmpeg_codecs';
31
32                /**
33                 * On recharge les logiciels
34                 */
35                $verifier_binaires = charger_fonction('spipmotion_verifier_binaires', 'inc');
36                $verifier_binaires();
37                if ($GLOBALS['spipmotion_metas']['spipmotion_safe_mode'] == 'oui') {
38                        $spipmotion_sh = $GLOBALS['spipmotion_metas']['spipmotion_safe_mode_exec_dir'].'/spipmotion.sh';
39                } else {
40                        $spipmotion_sh = find_in_path('script_bash/spipmotion.sh');
41                }
42
43                /**
44                 * On crée un fichier contenant l'ensemble de la conf de ffmpeg
45                 */
46                supprimer_fichier($chemin_fichier);
47                spimotion_write($chemin_fichier, "==VERSION==\n");
48                exec($spipmotion_sh.' --info "-version" --log '.$chemin_fichier, $retour, $bool);
49                spimotion_write($chemin_fichier.'_formats', "\n==FORMATS==\n");
50                exec($spipmotion_sh.' --info "-formats" --log '.$chemin_fichier.'_formats', $retour, $bool);
51                spimotion_write($chemin_fichier.'_codecs', "\n==CODECS==\n");
52                exec($spipmotion_sh.' --info "-codecs" --log '.$chemin_fichier.'_codecs', $retour, $bool);
53                spimotion_write($chemin_fichier, "\n==BSFS==\n");
54                exec($spipmotion_sh.' --info "-bsfs" --log '.$chemin_fichier, $retour, $bool);
55                spimotion_write($chemin_fichier, "\n==FILTERS==\n");
56                exec($spipmotion_sh.' --info "-filters" --log '.$chemin_fichier, $retour, $bool);
57                spimotion_write($chemin_fichier, "\n==PIX_FMTS==\n");
58                exec($spipmotion_sh.' --info "-pix_fmts" --log '.$chemin_fichier, $retour, $bool);
59                spimotion_write($chemin_fichier, "\n==PROTOCOLS==\n");
60                exec($spipmotion_sh.' --info "-protocols" --log '.$chemin_fichier, $retour, $bool);
61                spimotion_write($chemin_fichier, "\n==FIN==");
62
63                if (lire_fichier($chemin_fichier, $contenu)) {
64                        $contenu = trim($contenu);
65                        $data = array();
66                        $look_ups = array(
67                                'version' => 'ffmpeg version',
68                                'configuration'=>'configuration:',
69                                'bitstream_filters'=>'==BSFS==',
70                                'avfilters' => 'Filters:',
71                                'pix_formats' => '==PIX_FMTS==',
72                                'abbreviations'=>'Frame size, frame rate abbreviations:',
73                                'protocols'=>'==PROTOCOLS==',
74                                'fin' => '==FIN=='
75                        );
76
77                        $pregs = array();
78                        $indexs = array();
79                        foreach ($look_ups as $key => $reg) {
80                                if (strpos($contenu, $reg) !== false) {
81                                        $index = array_push($pregs, $reg);
82                                        $indexs[$key] = $index;
83                                }
84                        }
85                        $result = preg_match('/'.implode('(.*)', $pregs).'/s', $contenu, $matches);
86
87                        /**
88                         * Récupération des informations de version
89                         */
90                        $data['spipmotion_compiler'] = array();
91                        $data['spipmotion_compiler']['versions'] = array();
92
93                        $version = trim($matches[$indexs['version']]);
94                        preg_match('/([a-zA-Z0-9\-]+[0-9\.]+).* with gcc (.*)/s', $version, $versions);
95                        $data['spipmotion_compiler']['ffmpeg_version'] = $versions[1];
96                        $data['spipmotion_compiler']['gcc'] = $versions[2];
97
98                        /**
99                         * Récupération des éléments de configuration
100                         */
101                        $configuration = trim($matches[$indexs['configuration']]);
102                        preg_match_all('/--[a-zA-Z0-9\-]+/', $configuration, $config_flags);
103                        ksort($config_flags[0]);
104                        $data['spipmotion_compiler']['configuration'] = $config_flags[0];
105
106                        // Replace old vhook support
107                        $data['spipmotion_compiler']['avfilter-support'] = (in_array('--enable-avfilter', $config_flags[0]) && !in_array('--disable-avfilter', $config_flags[0]) ? '1' : '0');
108
109                        /**
110                         * Récupération des formats disponibles
111                         * Pour chaque format reconnu on retourne un array avec
112                         */
113                        if (lire_fichier($chemin_fichier.'_formats', $contenu_formats)) {
114                                $contenu_formats = explode("\n", $contenu_formats);
115                                $data['spipmotion_formats'] = array();
116                                foreach ($contenu_formats as $contenu_format) {
117                                        preg_match('/ (DE|D|E) (.*) {1,} (.*)/', $contenu_format, $formats);
118                                        $data['spipmotion_formats'][strtolower(trim($formats[2]))] = array(
119                                                'encode'        => $formats[1] == 'DE' || $formats[1] == 'E',
120                                                'decode'        => $formats[1] == 'DE' || $formats[1] == 'D',
121                                                'fullname'      => $formats[3]
122                                        );
123                                        $formats = false;
124                                }
125                                ecrire_config('/spipmotion_metas/spipmotion_formats', serialize($data['spipmotion_formats']));
126                        }
127                        $contenu_formats = false;
128
129                        /**
130                         * Récupération des codecs disponibles
131                         */
132                        if (lire_fichier($chemin_fichier.'_codecs', $contenu_codecs)) {
133                                $contenu_codecs = explode("\n", $contenu_codecs);
134                                $data['spipmotion_codecs'] = array();
135                                $data['spipmotion_codecs_audio_decode'] = array();
136                                $data['spipmotion_codecs_video_decode'] = array();
137                                $data['spipmotion_codecs_audio_encode'] = array();
138                                $data['spipmotion_codecs_video_encode'] = array();
139                                foreach ($contenu_codecs as $contenu_codec) {
140                                        preg_match('/ (D| |\.)(E| |\.)(V|A|S|\.)(S| |\.|I)(D|L| |\.)(T|S| ) (.*) {1,} (.*)/', $contenu_codec, $codecs);
141                                        $data['spipmotion_codecs'][strtolower(trim($codecs[7]))] = array(
142                                                'decode'        => $codecs[1] == 'D',
143                                                'encode'        => $codecs[2] == 'E',
144                                                'type'  => $codecs[3],
145                                                'draw_horiz_band'       => $codecs[4] == 'S',
146                                                'direct_rendering'      => $codecs[5] == 'D',
147                                                'weird_frame_truncation' => $codecs[6] == 'T',
148                                                'fullname' => $codecs[8]
149                                        );
150                                        if (($codecs[1] == 'D') && ($codecs[3] == 'A')) {
151                                                $data['spipmotion_codecs_audio_decode'][] = trim($codecs[7]);
152                                        }
153                                        if (($codecs[1] == 'D') && ($codecs[3] == 'V')) {
154                                                $data['spipmotion_codecs_video_decode'][] = trim($codecs[7]);
155                                        }
156                                        if (($codecs[2] == 'E') && ($codecs[3] == 'A')) {
157                                                $data['spipmotion_codecs_audio_encode'][] = trim($codecs[7]);
158                                        }
159                                        if (($codecs[2] == 'E') && ($codecs[3] == 'V')) {
160                                                $data['spipmotion_codecs_video_encode'][] = trim($codecs[7]);
161                                        }
162                                }
163                                ecrire_config('/spipmotion_metas/spipmotion_codecs', serialize($data['spipmotion_codecs']));
164                                ecrire_config('/spipmotion_metas/spipmotion_codecs_audio_decode', serialize($data['spipmotion_codecs_audio_decode']));
165                                ecrire_config('/spipmotion_metas/spipmotion_codecs_video_decode', serialize($data['spipmotion_codecs_video_decode']));
166                                ecrire_config('/spipmotion_metas/spipmotion_codecs_audio_encode', serialize($data['spipmotion_codecs_audio_encode']));
167                                ecrire_config('/spipmotion_metas/spipmotion_codecs_video_encode', serialize($data['spipmotion_codecs_video_encode']));
168                        }
169
170                        /**
171                         * On récupère les filtres bitstream disponibles
172                         */
173                        $bitstream_filters = trim($matches[$indexs['bitstream_filters']]);
174                        $data['spipmotion_bitstream_filters'] = empty($bitstream_filters) ? array() : preg_split('/\n/', $bitstream_filters);
175                        ecrire_config('/spipmotion_metas/spipmotion_bitstream_filters', serialize($data['spipmotion_bitstream_filters']));
176
177                        /**
178                         * On récupère les protocoles disponibles
179                         */
180                        $protocols = trim($matches[$indexs['protocols']]);
181                        $data['spipmotion_protocols'] = empty($protocols) ? array() : preg_split('/\n/', str_replace(':', '', $protocols));
182                        ecrire_config('/ecrire_config/spipmotion_protocols', serialize($data['spipmotion_protocols']));
183
184                        /**
185                         * On récupère la liste des filtres avfilter
186                         */
187                        preg_match_all('/(.*) {1,} (.*)/', trim($matches[$indexs['avfilters']]), $filters);
188                        $data['spipmotion_avfilters'] = array();
189                        for ($i=0, $a=count($filters[0]); $i<$a; $i++) {
190                                $data['spipmotion_avfilters'][strtolower(trim($filters[1][$i]))] = array(
191                                        'nom'   => trim($filters[1][$i]),
192                                        'description'   => trim($filters[2][$i]) == '(null)' ? false : trim($filters[2][$i]),
193                                );
194                        }
195                        if (empty($data['spipmotion_avfilters'])) {
196                                $data['spipmotion_compiler']['avfilter-support'] = false;
197                        }
198
199                        ksort($data['spipmotion_avfilters']);
200                        ecrire_config('/spipmotion_metas/spipmotion_avfilters', serialize($data['spipmotion_avfilters']));
201                        ecrire_config('/spipmotion_metas/spipmotion_compiler', serialize($data['spipmotion_compiler']));
202
203                        /**
204                         * On regarde si spipmotion.sh est utilisable
205                         */
206                        $spipmotion_infos_sh = exec($spipmotion_sh.' --help', $retour_spipmotion_sh, $int_spipmotion_sh);
207                        if (!empty($retour_spipmotion_sh)) {
208                                $info = $retour_spipmotion_sh[1];
209                                preg_match('/SPIPmotion v([0-9a-z].*)/s', $info, $infos);
210                                $data['spipmotion_spipmotion_sh']['spipmotion_sh'] = true;
211                                $data['spipmotion_spipmotion_sh']['chemin'] = $spipmotion_sh;
212                                $data['spipmotion_spipmotion_sh']['version'] = $infos[1];
213                                ecrire_config('/spipmotion_metas/spipmotion_spipmotion_sh', serialize($data['spipmotion_spipmotion_sh']));
214                        }
215
216                        /**
217                         * On regarde si spipmotion_vignettes.sh est utilisable
218                         */
219                        if ($GLOBALS['spipmotion_metas']['spipmotion_safe_mode'] == 'oui') {
220                                $spipmotion_sh_vignettes = $GLOBALS['spipmotion_metas']['spipmotion_safe_mode_exec_dir'].'/spipmotion_vignette.sh';
221                        } else {
222                                $spipmotion_sh_vignettes = find_in_path('script_bash/spipmotion_vignette.sh');
223                        }
224
225                        $spipmotion_sh_vignettes_infos = exec($spipmotion_sh_vignettes.' --help', $retour_spipmotion_sh_vignettes, $int_spipmotion_sh_vignettes);
226                        if (!empty($retour_spipmotion_sh_vignettes)) {
227                                $info = $retour_spipmotion_sh_vignettes[2];
228                                preg_match('/SPIPmotion vignette v([0-9a-z].*)/s', $info, $infos);
229                                $data['spipmotion_spipmotion_sh_vignettes']['spipmotion_sh_vignettes'] = true;
230                                $data['spipmotion_spipmotion_sh_vignettes']['chemin'] = $spipmotion_sh_vignettes;
231                                $data['spipmotion_spipmotion_sh_vignettes']['version'] = $infos[1];
232                                ecrire_config('/spipmotion_metas/spipmotion_spipmotion_sh_vignettes', serialize($data['spipmotion_spipmotion_sh_vignettes']));
233                        } else {
234                                $data['spipmotion_spipmotion_sh_vignettes']['spipmotion_sh_vignettes'] = false;
235                                if (strlen($spipmotion_sh_vignettes)) {
236                                        $data['spipmotion_spipmotion_sh_vignettes']['chemin'] = $spipmotion_sh_vignettes;
237                                }
238                                ecrire_config('/spipmotion_metas/spipmotion_spipmotion_sh_vignettes', serialize($data['spipmotion_spipmotion_sh_vignettes']));
239                        }
240
241                        /**
242                         * On regarde si flvtool++ est installé
243                         * http://mirror.facebook.net/facebook/flvtool++/
244                         * Si oui on ajoute sa version dans les metas aussi
245                         */
246                        $flvtoolplus = exec('flvtool++', $retour_flvtoolplus, $int_flvtoolplus);
247                        if (!empty($retour_flvtoolplus)) {
248                                $info = $retour_flvtoolplus[0];
249                                preg_match('/flvtool\+\+ ([0-9a-z].*)/s', $info, $infos);
250                                $data['spipmotion_flvtoolplus']['flvtoolplus'] = true;
251                                $data['spipmotion_flvtoolplus']['version'] = $infos[1];
252                                ecrire_config('/spipmotion_metas/spipmotion_flvtoolplus', serialize($data['spipmotion_flvtoolplus']));
253                        } else {
254                                effacer_config('/spipmotion_metas/spipmotion_flvtoolplus');
255                        }
256
257                        /**
258                         * On regarde si ffprobe est installé
259                         * Si oui on dit juste qu'il est présent
260                         */
261                        $ffprobe = exec('ffprobe --version', $retour_ffprobe, $int_ffprobe);
262                        if ($int_ffprobe == 0) {
263                                $data['spipmotion_ffprobe']['ffprobe'] = true;
264                                $data['spipmotion_ffprobe']['version'] = 'present';
265                                ecrire_config('/spipmotion_metas/spipmotion_ffprobe', serialize($data['spipmotion_ffprobe']));
266                        } else {
267                                effacer_config('/spipmotion_metas/spipmotion_ffprobe');
268                        }
269
270                        /**
271                         * On regarde si mediainfo est installé
272                         * http://mediainfo.sourceforge.net/fr
273                         * Si oui on ajoute sa version dans les metas aussi
274                         */
275                        $mediainfo = exec('mediainfo --version', $retour_mediainfo, $int_mediainfo);
276                        if (!empty($retour_mediainfo)) {
277                                $info = $retour_mediainfo[1];
278                                preg_match('/MediaInfoLib - ([0-9a-z].*)/s', $info, $infos);
279                                $data['spipmotion_mediainfo']['mediainfo'] = true;
280                                $data['spipmotion_mediainfo']['version'] = $infos[1];
281                                ecrire_config('/spipmotion_metas/spipmotion_mediainfo', serialize($data['spipmotion_mediainfo']));
282                        } else {
283                                effacer_config('/spipmotion_metas/spipmotion_mediainfo');
284                        }
285
286                        $inc_meta = charger_fonction('meta', 'inc');
287                        $inc_meta('spipmotion_metas');
288                }
289        } else {
290                $data = array();
291                $data['spipmotion_spipmotion_sh'] = unserialize($GLOBALS['spipmotion_metas']['spipmotion_spipmotion_sh']);
292                $data['spipmotion_spipmotion_sh_vignettes'] = unserialize($GLOBALS['spipmotion_metas']['spipmotion_spipmotion_sh_vignettes']);
293                $data['spipmotion_compiler'] = unserialize($GLOBALS['spipmotion_metas']['spipmotion_compiler']);
294                $data['spipmotion_formats'] = unserialize($GLOBALS['spipmotion_metas']['spipmotion_formats']);
295                $data['spipmotion_codecs'] = unserialize($GLOBALS['spipmotion_metas']['spipmotion_codecs']);
296                $data['spipmotion_bitstream_filters'] = unserialize($GLOBALS['spipmotion_metas']['spipmotion_bitstream_filters']);
297                $data['spipmotion_protocols'] = unserialize($GLOBALS['spipmotion_metas']['spipmotion_protocols']);
298                $data['spipmotion_avfilters'] = unserialize($GLOBALS['spipmotion_metas']['spipmotion_avfilters']);
299                $data['spipmotion_flvtoolplus'] = unserialize($GLOBALS['spipmotion_metas']['spipmotion_flvtoolplus']);
300                $data['spipmotion_mediainfo'] = unserialize($GLOBALS['spipmotion_metas']['spipmotion_mediainfo']);
301                $data['spipmotion_ffprobe'] = unserialize($GLOBALS['spipmotion_metas']['spipmotion_ffprobe']);
302        }
303        return $data;
304}
305
306function spimotion_write($chemin_fichier, $what) {
307        $f = @fopen($chemin_fichier, 'ab');
308        if ($f) {
309                fputs($f, "$what\n");
310                fclose($f);
311        }
312}
Note: See TracBrowser for help on using the repository browser.