Obtener tags de videos con PHP

Buscando alguna clase para PHP con la que pudiera obtener los tags de información de cualquier tipo de archivo multimedia (AVI, MP3) he descubierto una utilidad bastante interesante, no es una librería de PHP sino una herramienta externa con la cual podremos procesar cualquier archivo de video y obtener toda la información disponible del mismo.

512px-MediaInfo_LogoLa herramienta se llama MediaInfo y es un programa ejecutable al que pasándole la ruta del archivo nos devuelve toda la información, la cual podemos analizar y utilizar solo los campos necesarios.

Lo primero que debemos hacer es descargarnos la última versión de MediaInfo pero solo el cliente (esta explicación la haré para Windows pero utilizando el mismo procedimiento es totalmente compatible con Linux).

Una vez descargado, descomprimimos el archivo ZIP y ubicamos los archivos en algún lugar de fácil acceso, en mi caso c:\Program Files\MediaInfoShell\.

La sintaxis para obtener la información de un video es la siguiente:

mediainfo.exe -f filepath

Utilizando la función shell_exec de PHP obtendríamos un string con todo el contenido, para el caso de Windows y olvidarnos de las rutas relativas, esta es la línea de ejecución:

$filepath = escapeshellarg($filepath);
$comando = "\"c:\\Program Files\\MediaInfoShell\mediainfo.exe\" -f $filepath";
$media_data = shell_exec($comando);

Donde filepath podría ser por ejemplo: C:/Users/Usuario/Videos.

Yo he creado una estructura en una base de datos de 3 tablas, una para la información general del video, otra solo para los streams de video y otra para los canales de audio. Existen muchísimos más campos que te devuelve este comando pero a mi entender los más importantes son los que pongo a continuación:

Tabla para la información general del archivo

CREATE TABLE `file` (
  `file_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `file_creation_date` datetime NOT NULL,
  `file_extension` varchar(4) NOT NULL,
  `file_last_modification_date` datetime NOT NULL,
  `file_name` varchar(150) NOT NULL,
  `file_size` bigint(15) unsigned NOT NULL,
  `codec` varchar(20) NOT NULL,
  `codec_url` varchar(150) DEFAULT NULL,
  `codec_id` varchar(50) DEFAULT NULL,
  `codec_id_url` varchar(150) DEFAULT NULL,
  `codecs_video` varchar(30) NOT NULL,
  `complete_name` varchar(255) NOT NULL,
  `count_of_audio_streams` enum('1','2','3','4','5') NOT NULL,
  `count_of_menu_streams` tinyint(3) unsigned DEFAULT NULL,
  `count_of_text_streams` tinyint(3) unsigned DEFAULT NULL,
  `count_of_video_streams` enum('1','2','3','4','5') NOT NULL,
  `audio_codecs` varchar(50) NOT NULL,
  `audio_format_list` varchar(50) NOT NULL,
  `audio_language_list` varchar(100) DEFAULT NULL,
  `duration` int(10) unsigned NOT NULL,
  `format` varchar(20) NOT NULL,
  `format_profile` varchar(50) DEFAULT NULL,
  `format_url` varchar(150) DEFAULT NULL,
  `format_version` varchar(50) DEFAULT NULL,
  `overall_bit_rate` int(10) unsigned NOT NULL,
  `overall_bit_rate_mode` enum('CBR','VBR') DEFAULT NULL,
  `writing_application` varchar(120) DEFAULT NULL,
  `writing_library` varchar(60) DEFAULT NULL,
  `video_format_list` varchar(30) NOT NULL,
  `video_language_list` varchar(100) DEFAULT NULL,
  `encoded_date` datetime DEFAULT NULL,
  `tagged_date` datetime DEFAULT NULL,
  `unique_id` varchar(70) DEFAULT NULL,
  `internet_media_type` varchar(20) DEFAULT NULL,
  `interleaved` enum('No','Yes') DEFAULT NULL,
  `stream_size` int(10) unsigned DEFAULT NULL,
  `proportion_of_this_stream` float unsigned DEFAULT NULL,
  `text_language_list` varchar(150) DEFAULT NULL,
  `isstreamable` enum('No','Yes') DEFAULT NULL,
  PRIMARY KEY (`file_id`),
  UNIQUE KEY `UK_filepath` (`file_name`,`file_extension`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Tabla con el contenido de los canales de video

CREATE TABLE `file_video` (
  `file_video_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `file` int(10) unsigned NOT NULL,
  `format` varchar(20) DEFAULT NULL,
  `format_profile` varchar(35) DEFAULT NULL,
  `format_settings` varchar(50) DEFAULT NULL,
  `format_url` varchar(100) DEFAULT NULL,
  `format_version` enum('Version 1','Version 2') DEFAULT NULL,
  `duration` mediumint(10) unsigned DEFAULT NULL,
  `bit_rate` int(8) unsigned DEFAULT NULL,
  `width` smallint(4) unsigned NOT NULL,
  `height` smallint(4) unsigned NOT NULL,
  `display_aspect_ratio` float DEFAULT NULL,
  `frame_count` mediumint(6) unsigned DEFAULT NULL,
  `frame_rate` char(6) DEFAULT NULL,
  `frame_rate_mode` enum('CFR','VFR') DEFAULT NULL,
  `color_space` enum('YUV') DEFAULT NULL,
  `chroma_subsampling` char(5) DEFAULT NULL,
  `bit_depth` enum('8','10') DEFAULT NULL,
  `scan_type` enum('Interlaced','Progressive','MBAFF') DEFAULT NULL,
  `compression_mode` enum('Lossy') DEFAULT NULL,
  `bits_pixel_frame` float DEFAULT NULL,
  `stream_size` bigint(10) unsigned DEFAULT NULL,
  `streamorder` varchar(5) DEFAULT NULL,
  `count_of_stream_of_this_kind` enum('1','2','3','4','5') NOT NULL,
  `commercial_name` varchar(20) NOT NULL,
  `internet_media_type` varchar(20) DEFAULT NULL,
  `codec` varchar(20) NOT NULL,
  `codec_family` varchar(10) DEFAULT NULL,
  `codec_info` varchar(30) DEFAULT NULL,
  `codec_url` varchar(100) DEFAULT NULL,
  `codec_cc` varchar(10) DEFAULT NULL,
  `codec_profile` varchar(50) DEFAULT NULL,
  `codec_settings_packet_bitstream` enum('No','Yes') DEFAULT NULL,
  `codec_settings_bvop` enum('No','Yes') DEFAULT NULL,
  `codec_settings_qpel` enum('No','Yes') DEFAULT NULL,
  `codec_settings_gmc` enum('0','1','2','3','4','5') DEFAULT NULL,
  `codec_settings_matrix` varchar(20) DEFAULT NULL,
  `codec_id` varchar(20) DEFAULT NULL,
  `codec_id_hint` varchar(20) DEFAULT NULL,
  `codec_id_url` varchar(100) DEFAULT NULL,
  `pixel_aspect_ratio` float NOT NULL,
  `resolution` enum('8','10') DEFAULT NULL,
  `colorimetry` char(5) DEFAULT NULL,
  `interlacement` enum('BFF','Interlaced','MBAFF','PPF','TFF') DEFAULT NULL,
  `delay` int(10) unsigned DEFAULT NULL,
  `proportion_of_this_stream` float DEFAULT NULL,
  `writing_library` varchar(80) DEFAULT NULL,
  `writing_library_name` varchar(50) DEFAULT NULL,
  `writing_library_version` varchar(70) DEFAULT NULL,
  `writing_library_date` datetime DEFAULT NULL,
  `muxing_mode` enum('Header stripping','Packed bitstream') DEFAULT NULL,
  `standard` enum('NTSC','PAL') DEFAULT NULL,
  `time_code_of_first_frame` char(11) DEFAULT NULL,
  `buffer_size` int(10) unsigned DEFAULT NULL,
  `bit_rate_mode` enum('CBR','VBR') DEFAULT NULL,
  `source_duration` mediumint(10) unsigned DEFAULT NULL,
  `source_encoded_stream_size` varchar(50) DEFAULT NULL,
  `codec_description` varchar(50) DEFAULT NULL,
  `language` varchar(10) DEFAULT NULL,
  `nominal_bit_rate` int(10) unsigned DEFAULT NULL,
  `nominal_frame_rate` char(6) DEFAULT NULL,
  `original_frame_rate` float DEFAULT NULL,
  `original_pixel_aspect_ratio` float DEFAULT NULL,
  `original_display_aspect_ratio` float DEFAULT NULL,
  `unique_id` varchar(50) DEFAULT NULL,
  `colour_description_present` enum('Yes','No') DEFAULT NULL,
  `color_primaries` varchar(20) DEFAULT NULL,
  `forced` enum('Yes','No') DEFAULT NULL,
  `minimum_frame_rate` char(6) DEFAULT NULL,
  `maximum_frame_rate` char(6) DEFAULT NULL,
  `maximum_bit_rate` int(10) unsigned DEFAULT NULL,
  `encoded_date` datetime DEFAULT NULL,
  `encoded_bit_rate` int(10) unsigned DEFAULT NULL,
  `encoded_stream_size` bigint(10) unsigned DEFAULT NULL,
  `tagged_date` datetime DEFAULT NULL,
  `streamsize_encoded_proportion` float DEFAULT NULL,
  PRIMARY KEY (`file_video_id`),
  KEY `FK_file_video` (`file`),
  CONSTRAINT `FK_file_video` FOREIGN KEY (`file`) REFERENCES `file` (`file_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Tabla con el contenido de los canales de audio

CREATE TABLE `file_audio` (
  `file_audio_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `file` int(10) unsigned NOT NULL,
  `format` varchar(20) NOT NULL,
  `format_url` varchar(100) DEFAULT NULL,
  `format_version` varchar(20) DEFAULT NULL,
  `format_profile` varchar(20) DEFAULT NULL,
  `format_settings` varchar(50) DEFAULT NULL,
  `format_settings_endianness` varchar(10) DEFAULT NULL,
  `format_settings_sign` enum('Signed') DEFAULT NULL,
  `mode` varchar(20) DEFAULT NULL,
  `mode_extension` varchar(30) DEFAULT NULL,
  `duration` int(10) unsigned NOT NULL,
  `bit_depth` enum('4','16','24') DEFAULT NULL,
  `bit_rate` bigint(20) unsigned DEFAULT NULL,
  `bit_rate_mode` enum('CBR','VBR') DEFAULT NULL,
  `minimum_bit_rate` int(10) unsigned DEFAULT NULL,
  `nominal_bit_rate` mediumint(6) unsigned DEFAULT NULL,
  `channel_s` enum('1','2','3','4','5','6','7','8','9') NOT NULL,
  `channel_positions` varchar(40) DEFAULT NULL,
  `sampling_rate` varchar(20) NOT NULL,
  `compression_mode` varchar(20) DEFAULT NULL,
  `stream_size` int(10) unsigned DEFAULT NULL,
  `alignment` enum('Aligned','Split') DEFAULT NULL,
  `interleave_duration` float DEFAULT NULL,
  `interleave_preload_duration` smallint(4) unsigned DEFAULT NULL,
  `count_of_stream_of_this_kind` enum('1','2','3','4','5') NOT NULL,
  `streamorder` varchar(5) DEFAULT NULL,
  `commercial_name` varchar(20) NOT NULL,
  `internet_media_type` varchar(20) DEFAULT NULL,
  `codec` varchar(20) NOT NULL,
  `codec_description` varchar(100) DEFAULT NULL,
  `codec_family` varchar(10) DEFAULT NULL,
  `codec_info` varchar(50) DEFAULT NULL,
  `codec_url` varchar(100) DEFAULT NULL,
  `codec_profile` varchar(20) DEFAULT NULL,
  `codec_id` varchar(10) DEFAULT NULL,
  `codec_id_hint` varchar(10) DEFAULT NULL,
  `codec_id_url` varchar(100) DEFAULT NULL,
  `codec_settings_endianness` enum('Big','Little') DEFAULT NULL,
  `codec_settings_sign` varchar(50) DEFAULT NULL,
  `samples_count` bigint(20) unsigned DEFAULT NULL,
  `delay` float DEFAULT NULL,
  `delay_origin` varchar(50) DEFAULT NULL,
  `proportion_of_this_stream` float DEFAULT NULL,
  `writing_library` text,
  `channellayout` varchar(50) DEFAULT NULL,
  `resolution` enum('4','16','24') DEFAULT NULL,
  `bsid` enum('4','6','8') DEFAULT NULL,
  `dsurmod` enum('0','1','2') DEFAULT NULL,
  `acmod` enum('1','2','3','4','5','6','7') DEFAULT NULL,
  `lfeon` enum('0','1') DEFAULT NULL,
  `dialnorm` tinyint(4) DEFAULT NULL,
  `dialnorm_average` tinyint(4) DEFAULT NULL,
  `dialnorm_minimum` tinyint(4) DEFAULT NULL,
  `dialnorm_maximum` tinyint(4) DEFAULT NULL,
  `dialnorm_count` mediumint(8) unsigned DEFAULT NULL,
  `encoding_settings` varchar(150) DEFAULT NULL,
  `source_duration` bigint(10) unsigned DEFAULT NULL,
  `source_stream_size` bigint(20) unsigned DEFAULT NULL,
  `source_streamsize_proportion` float DEFAULT NULL,
  `frame_count` mediumint(6) unsigned DEFAULT NULL,
  `language` varchar(50) DEFAULT NULL,
  `dsurmod_string` enum('Dolby Surround encoded','Not Dolby Surround encoded') DEFAULT NULL,
  `encoded_date` datetime DEFAULT NULL,
  `tagged_date` datetime DEFAULT NULL,
  `unique_id` varchar(50) DEFAULT NULL,
  `default` enum('No','Yes') DEFAULT NULL,
  `forced` enum('No','Yes') DEFAULT NULL,
  `channel_s_original` enum('1','2','3','4','5','6','7','8','9') DEFAULT NULL,
  `muxing_mode` varchar(20) DEFAULT NULL,
  `codec_cc` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`file_audio_id`),
  KEY `FK_file_audio` (`file`),
  CONSTRAINT `FK_file_audio` FOREIGN KEY (`file`) REFERENCES `file` (`file_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Como se puede apreciar la información almacenada es bastante descriptiva y los tipos de archivos soportados son innumerables.

Bueno, hasta aquí tenemos la herramienta para sacar la información de una archivo de video o audio (incluso de imágenes) con PHP y la base de datos donde guardar estos datos. Ahora veamos como analizar y formatear estos datos de cualquier archivo multimedia con PHP para poder insertarlos en las tablas anteriores.

Eliminamos todos los saltos de línea y recorremos línea a línea el resultado

$arrData = explode("\n", $media_data);

Eliminamos las lineas que indican el inicio de un tipo de contenido

if(stripos($data, "General") === 0){

}
elseif(stripos($data, "Video") === 0){

}
elseif(stripos($data, "Audio") === 0){

}

Analizamos los datos de cada línea con la información del archivo multimedia

$data = trim($data);
if(!empty($data)){
    if(strpos($data, " : ") !== FALSE){
           list($campo, $valor) = explode(" : ", $data);
           $conservar = 'a-z';
           $regex = sprintf('~[^%s]++~i', $conservar);
           $campo = str_replace(" ", "_", trim(preg_replace($regex, ' ', strtolower($campo))));
     }
}

Con esto tendríamos almacenado en la variable campo el campo de la base de datos y en valor el valor del mismo.

No es un script terminado es más bien orientativo para que cada uno según sus necesidades pueda sacar los datos de un archivo multimedia con PHP, ya sea audio o video, es válido para extraer la información de un AVI como pata los tags ID3 de los archivos MP3.

Comentarios