Some mosaics in same instance vlc

Discussion about configuration and usage of VLM (a stream scheduler) within VLC.
cmcm
New Cone
New Cone
Posts: 3
Joined: 30 Oct 2007 16:49

Some mosaics in same instance vlc

Postby cmcm » 30 Oct 2007 16:55

Hi all, i'm trying create 4 mosaic in same vlc instance, it's possible??

sorry for my bad english, thank you

mxm
New Cone
New Cone
Posts: 7
Joined: 07 Nov 2007 06:51

Re: Some mosaics in same instance vlc

Postby mxm » 09 Nov 2007 02:59

http://wiki.videolan.org/Mosaic - is it you want?
Post your vlm-conf. It helps to understand what you want.

cmcm
New Cone
New Cone
Posts: 3
Joined: 30 Oct 2007 16:49

Re: Some mosaics in same instance vlc

Postby cmcm » 12 Nov 2007 13:44

No mxm, I wanted to create 4 mosaics in 1 vlc instance.
At the end i had to create 4 instances vlc, 1 for mosaic.
Thank's for your answer mxm.
Sorry for my bad english.

Here my php class for this action:

Code: Select all

<?php //Clase para gestión de flujos VLC class vlc { var $host = "localhost"; //Host/Ip del servidor VLC var $arr_port = array(10001, 10002, 10003, 10004); //Puertos por los que escuchan los interfaces telnet var $arr_password = array("admin", "admin", "admin", "admin"); //Passwords para los interfaces telnet var $delay = 500000; //Retardo tras mandar un comando telnet (microsegundos, 1 segundo = 1.000.000 microsegundos) private $arr_fp = array(false, false, false, false); //Descriptores de socket private $str_output_codif = "#bridge-in:transcode{sfilter=mosaic,vcodec=mp4v,vb=4096}:"; //Lanza comandos contra el interface telenet de VLC //$num_flujo: numero 0...3 //$arr_commands: array con comandos telnet private function comandos_telnet($num_flujo, $arr_commands) { //Abrimos socket(si es necesario), si falla sale devolviendo false if ( $this->arr_fp[$num_flujo] === false ) { $this->arr_fp[$num_flujo] = fsockopen($this->host, $this->arr_port[$num_flujo], $errno, $errstr); $abierto = false; } else { $abierto = true; } //Inicializamos la salida vacia $output = ""; //Introducimos password si el socket no estaba abierto if ( $abierto === false ) { fputs($this->arr_fp[$num_flujo], $this->arr_password[$num_flujo]."\r\n"); usleep($this->delay); } //Creamos archivo temporal con los comandos si hay más de uno y redefinimos comandos telnet if ( count($arr_commands) > 1 ) { $vlm_file_temp = '/var/www/mysite/files/vlm_temp/'.time().'_'.rand(); $fp_temp = fopen($vlm_file_temp, 'w'); foreach ($arr_commands as $command) { fputs($fp_temp, $command."\r\n"); } fclose($fp_temp); $command = "load ".$vlm_file_temp; } else if ( count($arr_commands) == 1 ) { $command = $arr_commands[0]; } else { echo 'Error: Ningun comando pasado al método "comandos_telenet".'; return false; } //Lanzamos comando fputs($this->arr_fp[$num_flujo], $command."\r\n"); usleep($this->delay); $output .= fread($this->arr_fp[$num_flujo], 1024); //Borramos archivo temporal if ( count($arr_commands) > 1 ) { unlink($vlm_file_temp); } //Salimos de telnet y cerramos socket (comenatado para reutilizar misma conexión para todo un script) //fputs($this->fp, "exit\r\n"); //fclose($this->fp); //Devolvemos la salida en un array(cada posición una linea) $output = explode("\r\n", $output); if ( $abierto === false ) { $output = array_slice($output, 2); } //Kitamos lineas del password si conectamos en esta llamada return $output; } //Crea los 4 flujos vacios, en caso de ya existir alguno no lo crea, no devuelve nada function restore_flujos() { if ( $_SERVER['argc'] === 2 && $_SERVER['argv'][1] == 'restore' ) { echo "Restaurando flujos (PHP) ...\r\n"; } $arr_commands = array ( "new bg0 broadcast enabled", "setup bg0 input fake:", "setup bg0 option fake-file=/var/www/mysite/img/bg0.jpg", "setup bg0 option fake-aspect-ratio=4:3", "setup bg0 option fake-width=640", "setup bg0 option fake-height=480", "setup bg0 option mosaic-width=640", "setup bg0 option mosaic-height=480", "setup bg0 option mosaic-align=0", "setup bg0 output ".$this->str_output_codif."std{access=udp{ttl=99},mux=ts,dst=234.5.6.7:8910}", "control bg0 play", "new pb0 broadcast enabled", "setup pb0 output #duplicate{dst=mosaic-bridge{id=1},select=video,dst=bridge-out{id=1},select=audio}" ); $this->comandos_telnet(0, $arr_commands); $arr_commands = array ( "new bg1 broadcast enabled", "setup bg1 input fake:", "setup bg1 option fake-file=/var/www/mysite/img/bg0.jpg", "setup bg1 option fake-aspect-ratio=4:3", "setup bg1 option fake-width=640", "setup bg1 option fake-height=480", "setup bg1 option mosaic-width=640", "setup bg1 option mosaic-height=480", "setup bg1 option mosaic-align=0", "setup bg1 output ".$this->str_output_codif."std{access=udp{ttl=99},mux=ts,dst=234.5.6.7:8911}", "control bg1 play", "new pb1 broadcast enabled", "setup pb1 output #duplicate{dst=mosaic-bridge{id=1},select=video,dst=bridge-out{id=1},select=audio}" ); $this->comandos_telnet(1, $arr_commands); $arr_commands = array ( "new bg2 broadcast enabled", "setup bg2 input fake:", "setup bg2 option fake-file=/var/www/mysite/img/bg0.jpg", "setup bg2 option fake-aspect-ratio=4:3", "setup bg2 option fake-width=640", "setup bg2 option fake-height=480", "setup bg2 option mosaic-width=640", "setup bg2 option mosaic-height=480", "setup bg2 option mosaic-align=0", "setup bg2 output ".$this->str_output_codif."std{access=udp{ttl=99},mux=ts,dst=234.5.6.7:8912}", "control bg2 play", "new pb2 broadcast enabled", "setup pb2 output #duplicate{dst=mosaic-bridge{id=1},select=video,dst=bridge-out{id=1},select=audio}" ); $this->comandos_telnet(2, $arr_commands); $arr_commands = array ( "new bg3 broadcast enabled", "setup bg3 input fake:", "setup bg3 option fake-file=/var/www/mysite/img/bg0.jpg", "setup bg3 option fake-aspect-ratio=4:3", "setup bg3 option fake-width=640", "setup bg3 option fake-height=480", "setup bg3 option mosaic-width=640", "setup bg3 option mosaic-height=480", "setup bg3 option mosaic-align=0", "setup bg3 output ".$this->str_output_codif."std{access=udp{ttl=99},mux=ts,dst=234.5.6.7:8913}", "control bg3 play", "new pb3 broadcast enabled", "setup pb3 output #duplicate{dst=mosaic-bridge{id=1},select=video,dst=bridge-out{id=1},select=audio}" ); $this->comandos_telnet(3, $arr_commands); //*****************************************// //AKI RESTAURACIÓN MEDIANTE CONSULTA A BBDD// //*****************************************// } //Añade un video a un flujo al final de la lista de vlc (no posible insertarlo en otro lado), devuelve true/false //$num_flujo: número de flujo al q vamos a añadir el video (0...3) //$ruta_absoluta: ruta del video en el servidor function add_item($num_flujo, $ruta_absoluta) { $arr_output = $this->comandos_telnet($num_flujo, array("setup pb".$num_flujo." input ".$ruta_absoluta)); if ( $arr_output === false ) { return $arr_salida; } //Devuelve false return true; } //Borra un video de un flujo //$num_flujo: número de flujo al q vamos a borrar un video (0...3) //$num_orden: orden del video en la lista del VLC (0...n) function del_item($num_flujo, $num_orden) { //Ajustamos parametro $num_orden += 1; //Comprobación de rango de $num_orden $arr_items = $this->get_items($num_flujo); if ( $num_orden < 0 || $num_orden > count($arr_items)-1 ) { return false; } $arr_output = $this->comandos_telnet($num_flujo, array("setup pb".$num_flujo." inputdeln ".$num_orden)); if ( $arr_output === false ) { return $arr_salida; } //Devuelve false return true; } //Deja un flujo como aparecen inicialmente, sin videos, en estado enabled, si definir output //$num_flujo: número de flujo (0...3) function del_all($num_flujo) { $num_items = count( $this->get_items($num_flujo) ); if ( $num_items > 0 ) { for ( $i=$num_items ; $i>0 ; $i-- ) { $arr_commands[] = "setup pb".$num_flujo." inputdeln ".$i; } } else { return true; } $arr_output = $this->comandos_telnet($num_flujo, $arr_commands); if ( $arr_output === false ) { return $arr_salida; } //Devuelve false else { return true; } } //Devuelve array de videos del flujo $num_flujo //$num_flujo: número de flujo (0...3) function get_items($num_flujo) { $arr_output = $this->comandos_telnet($num_flujo, array("show pb".$num_flujo)); if ( $arr_output === false ) { return $arr_salida; } //Devuelve false $arr_salida = array(); for ( $i=0 ; $i<count($arr_output) ; $i++ ) { if ( trim($arr_output[$i]) == 'inputs' ) { if ( strpos(trim($arr_output[$i+1]), 'output') === 0 ) { return $arr_salida; } //Devuelve array vacio else { for ( $j=$i+1 ; $j<count($arr_output) ; $j++ ) { if ( strpos(trim($arr_output[$j]), 'output') === 0 ) { return $arr_salida; } //Devuelve array de videos ordenados else { $arr_salida[] = trim($arr_output[$j]); } } } } } } //Establece las opciones de salida del flujo. Si el flujo se está reproducciendo debemos hacer stop y luego play para que funcione //$num_flujo: número de flujo (0...3) //$address: ip/host por el que serviremos (si $multicast == true ---> 224.x.x.x - 239.x.x.x, 240.0.0.0 no es válida) //$port: puerto por el q serviremos //$multicast: true/false ---> udp/http function set_output($num_flujo, $address, $port, $multicast) { if ( $multicast === true ) { $acces = 'udp'; $ttl = '{ttl=99}'; } else if ( $multicast === false ) { $acces = 'http'; $ttl = ''; } $arr_commands[] = "control bg".$num_flujo." stop"; $arr_commands[] = "setup bg".$num_flujo." output ".$this->str_output_codif."std{access=".$acces.$ttl.",mux=ts,dst=".$address.":".$port."}"; $arr_commands[] = "control bg".$num_flujo." play"; $arr_output = $this->comandos_telnet($num_flujo, $arr_commands); if ( $arr_output === false ) { return $arr_salida; } //Devuelve false else { return true; } } //Devuelve array asociativo con propiedades actuales de la salida, si no hay devuelve null //$num_flujo: número de flujo (0...3) function get_output($num_flujo) { $arr_output = $this->comandos_telnet($num_flujo, array("show bg".$num_flujo)); if ( $arr_output === false ) { return $arr_salida; } //Devuelve false $arr_salida = array(); for ( $i=0 ; $i<count($arr_output) ; $i++ ) { if ( strpos(trim($arr_output[$i]), 'output :' ) === 0 ) { if ( trim($arr_output[$i]) == 'output :' ) { return null; } $arr_salida['address'] = substr( trim($arr_output[$i]), strpos(trim($arr_output[$i]), 'dst=')+strlen('dst='), strrpos(trim($arr_output[$i]), ':')-(strpos(trim($arr_output[$i]), 'dst=')+strlen('dst=')) ); $arr_salida['port'] = intval(substr( trim($arr_output[$i]), strrpos(trim($arr_output[$i]), ':')+1, strrpos(trim($arr_output[$i]), '}')-strrpos(trim($arr_output[$i]), ':') )); if ( substr( trim($arr_output[$i]), strpos(trim($arr_output[$i]), 'access=')+strlen('access='), 1 ) == 'u' ) { $arr_salida['multicast'] = true; } else { $arr_salida['multicast'] = false; } break; } } return $arr_salida; } //Play //$num_flujo: número de flujo (0...3) //$num_elemento: número de elemento de la lista de ese flujo (0...n), null por defecto(inicio de la lista) function play($num_flujo,$num_elemento=null) { $command = "control pb".$num_flujo." play"; if ( $num_elemento != null ) { $command .= " ".$num_elemento; } $arr_output = $this->comandos_telnet($num_flujo, array($command)); if ( $arr_output === false ) { return $arr_salida; } //Devuelve false else { return true; } } //Pause //$num_flujo: número de flujo (0...3) function pause($num_flujo) { $command = "control pb".$num_flujo." pause"; $arr_output = $this->comandos_telnet($num_flujo, array($command)); if ( $arr_output === false ) { return $arr_salida; } //Devuelve false else { return true; } } //Stop //$num_flujo: número de flujo (0...3) function stop($num_flujo) { $command = "control pb".$num_flujo." stop"; $arr_output = $this->comandos_telnet($num_flujo, array($command)); if ( $arr_output === false ) { return $arr_salida; } //Devuelve false else { return true; } } //Seeking //$num_flujo: número de flujo (0...3) //$val_seek: // 10 : se situa en el 10% +10 : avanza un 10% -10 : retrocede un 10% // 10s : se situa en el segundo 10 +10s : avanza 10 segundo -10s : retrocede 10segundos // 10ms : se situa en el milisegundo 10 +10ms : avanza 10 milisegundo -10ms : miliretrocede 10segundos function seek($num_flujo, $val_seek) { $command = "control pb".$num_flujo." seek ".$val_seek; $arr_output = $this->comandos_telnet($num_flujo, array($command)); if ( $arr_output === false ) { return $arr_salida; } //Devuelve false else { return true; } } //Devuelve estado de reproducción del flujo ('stopped'/'playing'/'paused') //$num_flujo: número de flujo (0...3) function get_estado($num_flujo) { $command = "show pb".$num_flujo; $arr_output = $this->comandos_telnet($num_flujo, array($command)); if ( $arr_output === false ) { return $arr_salida; } //Devuelve false $arr_salida = array(); if ( trim($arr_output[ count($arr_output)-2 ]) == 'instances' ) { $arr_salida['state'] = 'stopped'; } else { for ( $i=0 ; $i<count($arr_output) ; $i++ ) { if ( trim($arr_output[$i]) == 'instances' ) { for ( $j=$i+2 ; $j<count($arr_output) ; $j++ ) { if ( strpos(trim($arr_output[$j]), 'state :') === 0 ) { $arr_salida['state'] = trim( substr(trim($arr_output[$j]), strpos(trim($arr_output[$j]), ':')+1) ); } else if ( strpos(trim($arr_output[$j]), 'position :') === 0 ) { $arr_salida['position'] = floatval(trim( substr(trim($arr_output[$j]), strpos(trim($arr_output[$j]), ':')+1) )); } else if ( strpos(trim($arr_output[$j]), 'time :') === 0 ) { $arr_salida['time'] = intval(trim( substr(trim($arr_output[$j]), strpos(trim($arr_output[$j]), ':')+1) )); } else if ( strpos(trim($arr_output[$j]), 'length :') === 0 ) { $arr_salida['length'] = intval(trim( substr(trim($arr_output[$j]), strpos(trim($arr_output[$j]), ':')+1) )); } else if ( strpos(trim($arr_output[$j]), 'playlistindex :') === 0 ) { $arr_salida['playlistindex'] = intval(trim( substr(trim($arr_output[$j]), strpos(trim($arr_output[$j]), ':')+1) ))-1; } } } } } return $arr_salida; } //Devuelve la url del flujo, si no está definido el output devuelve null //$num_flujo: número de flujo (0...3) function get_url($num_flujo) { $datos_flujo = $this->get_output($num_flujo); if ( $datos_flujo == null ) { return null; } else { if ( $datos_flujo['multicast'] === true ) { return 'udp://@'.$datos_flujo['address'].':'.$datos_flujo['port']; } else if ( $datos_flujo['multicast'] === false ) { return 'http://'.$datos_flujo['address'].':'.$datos_flujo['port']; } } } //Establecer imagen de fondo //$num_flujo: número de flujo (0...3) //$ruta_absoluta: ruta de la nueva imagen en el servidor function set_image($num_flujo, $ruta_absoluta) { $arr_commands[] = "control bg".$num_flujo." stop"; $arr_commands[] = "setup bg".$num_flujo." option fake-file=".$ruta_absoluta; $arr_commands[] = "control bg".$num_flujo." play"; $arr_output = $this->comandos_telnet($num_flujo, $arr_commands); if ( $arr_output === false ) { return $arr_salida; } //Devuelve false else { return true; } } //Obtener imagen de fondo //$num_flujo: número de flujo (0...3) function get_image($num_flujo) { $arr_commands[] = "show bg".$num_flujo; $arr_output = $this->comandos_telnet($num_flujo, $arr_commands); if ( $arr_output === false ) { return $arr_salida; } //Devuelve false for ( $i=0 ; $i<count($arr_output) ; $i++ ) { if ( strpos(trim($arr_output[$i]), 'fake-file=') === 0 ) { $ruta_img = substr( trim($arr_output[$i]), strlen('fake-file=') ); } } return $ruta_img; } //Establecer aspecto del flujo (proporción) //$num_flujo: número de flujo (0...3) //$aspecto: '4:3'/'16:9' function set_aspecto($num_flujo, $aspecto) { if ( $aspecto != '4:3' && $aspecto != '16:9' ) { echo 'Error: Aspecto no válido, debe ser 4:3 ó 16:9.'; return false; } $arr_commands[] = "control bg".$num_flujo." stop"; $arr_commands[] = "setup bg".$num_flujo." option fake-aspect-ratio=".$aspecto; $arr_commands[] = "control bg".$num_flujo." play"; $arr_output = $this->comandos_telnet($num_flujo, $arr_commands); if ( $arr_output === false ) { return $arr_salida; } //Devuelve false else { return true; } } //Obtener aspecto actual del flujo (proporción) //$num_flujo: número de flujo (0...3) function get_aspecto($num_flujo) { $arr_commands[] = "show bg".$num_flujo; $arr_output = $this->comandos_telnet($num_flujo, $arr_commands); if ( $arr_output === false ) { return $arr_salida; } //Devuelve false for ( $i=0 ; $i<count($arr_output) ; $i++ ) { if ( strpos(trim($arr_output[$i]), 'fake-aspect-ratio=') === 0 ) { $aspecto = substr( trim($arr_output[$i]), strlen('fake-aspect-ratio=') ); } } return $aspecto; } } //Creamos objeto de la clase definida $VLC = new vlc; ?>

mxm
New Cone
New Cone
Posts: 7
Joined: 07 Nov 2007 06:51

Re: Some mosaics in same instance vlc

Postby mxm » 14 Nov 2007 05:13

Yes, it is possible, but ... not so fine.
Sub filter mosaic display all streams bridged through mosaic-bridge. So... you may hide unwanted stream by specifing mosaic-position=2 and mosaic-offsets out of mosaic size.
For example, 2 streamed mosaic with 2 videos in each:

Code: Select all

new bg1 broadcast enabled setup bg1 input fake: setup bg1 option fake-file=/home/max/Videos/1.png setup bg1 option fake-width=400 option fake-height=600 setup bg1 output #transcode{sfilter=mosaic,soverlay,vcodec=mp4v,acodec=mp3,ab=64,channels=1,scale=1}:bridge-in{id-offset=100}:std{access=udp,mux=ts,dst=192.168.0.14:1234} setup bg1 option mosaic-order='1,2,3,4' setup bg1 option mosaic-width=400 option mosaic-height=600 setup bg1 option mosaic-position=2 setup bg1 option mosaic-keep-picture setup bg1 option mosaic-offsets=0,0,0,300,400,0,400,0 new bg2 broadcast enabled setup bg2 input fake: setup bg2 option fake-file=/home/max/Videos/1.png setup bg2 option fake-width=400 option fake-height=600 setup bg2 output #transcode{sfilter=mosaic,soverlay,vcodec=mp4v,acodec=mp3,ab=64,channels=1,scale=1}:bridge-in{id-offset=100}:std{access=udp,mux=ts,dst=192.168.0.14:1235} setup bg2 option mosaic-order='3,4,1,2' setup bg2 option mosaic-width=400 option mosaic-height=600 setup bg2 option mosaic-position=2 setup bg2 option mosaic-keep-picture setup bg2 option mosaic-offsets=0,0,0,300,400,0,400,0 new ch1 broadcast enabled setup ch1 option video-filter=vawe setup ch1 input /home/max/Videos/1.avi setup ch1 output #duplicate{dst=mosaic-bridge{id=1,width=400,height=300},select=video,dst=bridge-out{id=0},select=audio} new ch2 broadcast enabled setup ch2 input /home/max/Videos/2.avi setup ch2 output #duplicate{dst=mosaic-bridge{id=2,width=400,height=300},select=video,dst=bridge-out{id=1},select=audio} new ch3 broadcast enabled setup ch3 input /home/max/Videos/3.avi setup ch3 output #duplicate{dst=mosaic-bridge{id=3,width=400,height=300},select=video,dst=bridge-out{id=0},select=audio} new ch4 broadcast enabled setup ch4 input /home/max/Videos/4.avi setup ch4 output #duplicate{dst=mosaic-bridge{id=4,width=400,height=300},select=video,dst=bridge-out{id=0},select=audio}

mxm
New Cone
New Cone
Posts: 7
Joined: 07 Nov 2007 06:51

Re: Some mosaics in same instance vlc

Postby mxm » 15 Nov 2007 02:14

Sorry, I am wrong. It is impossible.

cmcm
New Cone
New Cone
Posts: 3
Joined: 30 Oct 2007 16:49

Re: Some mosaics in same instance vlc

Postby cmcm » 16 Nov 2007 22:57

Thank's for your answers mxm.


Return to “VLM”

Who is online

Users browsing this forum: No registered users and 8 guests