Quote:
Originally Posted by ABNormal
mò tocca a te fare la guida di tutto ciò che hai fatto, spiegandone obiettivi e tecniche usate.
mi raccomando :)
|
Beh...ci provo:
Obbiettivo: realizzare un sistema per la trasmissione di eventi live con due tracce audio (nel mio caso il motivo era che l’evento veniva tradotto simultaneamente in una seconda lingua) senza trasmettere due volte il flusso video.
Premessa: la realizzazione è fattibile se non vi è la necessità di trasmettere audio stereo per nessuna delle due tracce.
Requisiti hardwere: ciò a cui si deve arrivare è una situazione in cui in ingresso audio alla periferica di acquisizione (line-in della scheda audio, audio-in della scheda di acquisizione video ecc…) ci sia su un canale (ad esempio il canale sinistro) la prima traccia audio, sull’altro la seconda.
Nel mio caso era abbastanza fattibile perché la mia scheda di acquisizione video presentava un classico ingresso RCA per ogni canale a cui ho collegato direttamente le uscite del mixer (già mono) dei rispettivi microfoni (sul canale sinistro il microfono del relatore e sul destro quello del traduttore).
Come prima cosa mi sono registrato su livestream.com, creato il mio canale e verificato. Poi ho seguito
questa guida per poterlo utilizzare con Adobe Flash Media Encoder (attenzione: nelle impostazioni di quest’ultimo si deve settare l’acquisizione audio in stereo e tenere d’occhio il totale di banda necessaria che il programma calcola in quanto si deve tener presente che il flusso video+audio non deve (nel caso abbiate scelto il piano free su livestream.com) superare i 500 kbps).
A questo punto potete già fare un test per vedere se riuscite a trasmettere.
Veniamo ora al player.
Per poter utilizzare del proprio codice ho seguito le indicazioni di
questa pagina.
Come prima cosa bisogna ottenere questa developer key. Ciò che si deve fare è inserire l’URL della pagina che ospiterà il player. Una volta generata la chiave questa resterà tra le vostre chiavi anche se lasciate la pagina o uscite dall’account quindi non state a preoccuparvi di scriverla da qualche parte.
Sempre dalla stessa pagina ho scaricato le API per Flash (un file compresso con all’interno alcuni esempi di player già realizzati e i componenti base per crearne uno) e poi modificato il file “LivestreamPlayer-cs4.fla” (in particolare io ho usato Adobe Flash Professional CS5.5 per aprirlo e modificarlo) per ottenere un player personalizzato.
Oltre all’aspetto grafico che ciascuno può personalizzare come vuole , per quanto riguarda la parte di codice, si deve:
1) Editare la classe “livestreamPlayer” (è nella libreria del progetto) per inserire la Developer Key ottenuta in precedenza, impostare il nome dello stream (dev’essere uguale a quello che avete deciso di adottare in Adobe Flash Media Encoder), impostare i parametri come dimensione della parte destinata al video, tasti da mostrare (per maggiori dettagli guardate
qui ). Ecco il mio codice Actionscript 3 (in pratica è il codice modificato del file LivestreamPlayer.as; ho cercato di evidenziare le modifiche precedendole da alcuni commenti):
Code:
ackage com.livestream {
import flash.display.MovieClip;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.system.Security;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.EventDispatcher;
import flash.events.ProgressEvent;
import fl.events.SliderEvent;
import fl.controls.Slider;
import flash.system.LoaderContext;
import flash.system.ApplicationDomain;
import flash.system.SecurityDomain;
import flash.display.DisplayObject;
import flash.utils.setTimeout;
import flash.media.Sound;
import flash.media.SoundMixer;
public class LivestreamPlayer extends MovieClip
{
private static const API_URL:String
= "http://cdn.livestream.com/chromelessPlayer/v20/playerapi.swf";
private static const STOP_BUTTON:String = "livestreamPlayerStopButton";
private static const PLAY_BUTTON:String = "livestreamPlayerPlayButton";
private static const TOGGLEPLAY_BUTTON:String = "livestreamPlayerTogglePlayButton";
private static const FULLSCREEN_BUTTON:String = "livestreamPlayerFullscreenButton";
private static const VOLUME_SLIDER:String = "livestreamPlayerVolumeSlider";
private var mainTimeline:Object;
private var loader:Loader;
public var player:Object;
public var _interferenceEnabled = false;
public var _textOverlayEnabled = false;
public var _powerButtonEnabled = false;
public var _volumeOverlayEnabled = false;
public var _showThumbnail = false;
public var _showPlayButton = true;
public var _showPauseButton = true;
public var _showMuteButton = true;
public var _showFullscreenButton = false
public var _showSpinner = true;
public var _spinnerSize;
public var _devKey;
public var _autoLoad = true;
public var _loadDelay = 0;
public var _width = 320;
public var _height = 320;
public var _isAutoPlay:Boolean = true;
public var _channel:String = "prova_canale_livestream";
public function LivestreamPlayer():void
{
Security.allowDomain("cdn.livestream.com");
Security.loadPolicyFile("http://cdn.livestream.com/crossdomain.xml");
mainTimeline = stage.getChildAt(0);
loaderInfo.addEventListener(Event.COMPLETE, componentLoadedHandler);
}
private function componentLoadedHandler(event:Event):void
{
if (_autoLoad)
{
load();
}
else if (_loadDelay != 0)
{
setTimeout(load, _loadDelay * 1000);
}
}
public function load():void
{
loader = new Loader();
var url:URLRequest = new URLRequest(API_URL);
addChild(loader);
loader.contentLoaderInfo.addEventListener(Event.CO MPLETE, loaderCompleteHandler);
try
{ // this is how we load remotely
loader.load(url, new LoaderContext(true, ApplicationDomain.currentDomain, SecurityDomain.currentDomain));
}
catch (error:SecurityError)
{ // this is how we load locally
loader.load(url);
}
}
public override function get width():Number
{
return player ? player.width : 0;
}
public override function set width(val:Number):void
{
if (player)
{
player.width = val;
}
}
public override function get height():Number
{
return player ? player.height : 0;
}
public override function set height(val:Number):void
{
if (player)
{
player.height = val;
}
}
private function loaderCompleteHandler(event:Event):void
{
loader.contentLoaderInfo.removeEventListener(Event .COMPLETE, loaderCompleteHandler);
player = loader.content;
/* Qui ho inserito la dimensione della "finestra" destinata al video *
* I parametri originali erano *
* player.width = _width; *
* player.height = _height; */
player.width = 480;
player.height = 360;
trace('w:' + _width + ' h:' + _height);
onPlayerReady();
}
private function playerErrorHandler(event:Event):void
{
trace('LivestreamPlayer error: ' + Object(event).message);
}
private function onPlayerReady():void
{
player.addEventListener("errorEvent", playerErrorHandler);
bindClick(STOP_BUTTON, nullary(player.stop));
bindClick(PLAY_BUTTON, nullary(player.play));
//bindClick(TOGGLEPLAY_BUTTON, nullary(player.togglePlayback));
bindClick(FULLSCREEN_BUTTON, nullary(player.toggleFullscreen));
bindEvent(VOLUME_SLIDER, SliderEvent.CHANGE,
function(event:SliderEvent):void { player.volume = event.value / 10; });
var volumeSlider = mainTimeline.getChildByName(VOLUME_SLIDER);
if (volumeSlider)
{
(volumeSlider as Slider).value = player.volume * 10;
}
/* Qui ho modificato alcune proprietà */
//player.showThumbnail = _showThumbnail;
player.showThumbnail = false;
player.showPlayButton = true;
player.showPauseButton = true;
player.showMuteButton = true;
player.showSpinner = true;
player.showFullscreenButton= true;
/* Qui ho inserito la Developer Key */
//player.devKey = _devKey;
player.devKey = "zLZBnNyZNm-1H2BcoRSo13TrXvZazYwcAtbEy-P751jwd6IDg3OPErNeFHaxeW7Tjvjj_U8PzXhBbRSNdfaTiyH0 AxtRzaE3Okg5qSADikzI6mXInBixxlu0abxQmxCGPN9fz5J6gW 0Fxvwvo6hxNg";
/* Qui ho inserito il nome dello stream */
player.load("prova_canale_livestream");
if (_isAutoPlay)
{
player.play();
}
dispatchEvent(new Event("ready"));
}
private function bindClick(instanceName:String, callback:Function):void
{
bindEvent(instanceName, MouseEvent.CLICK, callback);
}
private function bindEvent(instanceName:String, event:String, callback:Function):void
{
var displayObject:DisplayObject = mainTimeline.getChildByName(instanceName);
if (displayObject)
{
trace("<LivestreamPlayer> Found object: " + instanceName + ", binding.");
displayObject.addEventListener(event, callback);
}
else
{
trace("<LivestreamPlayer> Couldn't find object with instance name: " + instanceName + ", skipping.");
}
}
private function nullary(f:Function):Function
{
return function(arg:*) { f(); };
}
}
}
2) Inserire il codice per la gestione del doppio audio nel documento principale. C’è da precisare che ho inserito due pulsanti sullo stage per selezionare la lingua di ascolto (i più il pulsante della lingua selezionata ha al suo fianco un segno di spunta che compare per evidenziare quale lingua è settata). Ecco il codice:
Code:
import flash.media.SoundMixer;
import flash.media.SoundChannel;
import flash.media.SoundTransform;
import flash.events.MouseEvent;
var suono:SoundTransform=SoundMixer.soundTransform;
suono.leftToLeft=1;
suono.leftToRight=1;
suono.rightToLeft=0;
suono.rightToRight=0;
SoundMixer.soundTransform=suono;
lingua1_btn.addEventListener(MouseEvent.CLICK, setLingua1);
lingua2_btn.addEventListener(MouseEvent.CLICK, setLingua2);
lingua2_ceck.visible=false;
lingua1_ceck.enabled=false;
//lingua1_btn.enabled=false;
//lingua2_btn.enabled=false;
/* Estende il canale sinistro del video ad entrambi i canali in output */
function setLingua1(e:MouseEvent){
var suono:SoundTransform=SoundMixer.soundTransform;
suono.leftToLeft=1;
suono.leftToRight=1;
suono.rightToLeft=0;
suono.rightToRight=0;
SoundMixer.soundTransform=suono;
lingua1_ceck.visible=true;
lingua2_ceck.visible=false;
}
/* Estende il canale destro del video ad entrambi i canali in output */
function setLingua2(e:MouseEvent){
var suono:SoundTransform=SoundMixer.soundTransform;
suono.leftToLeft=0;
suono.leftToRight=0;
suono.rightToLeft=1;
suono.rightToRight=1;
SoundMixer.soundTransform=suono;
lingua2_ceck.visible=true;
lingua1_ceck.visible=false;
}
Ora non resta che esportare il video e inserirlo nella pagina HTML del vostro sito.
Ci tengo a dire che prima di ora la mia unica esperienza con Flash è stata attraverso YouTube…ciò che volgio dire è che non avevo mai usato Flash, Actionscript & Co. Quindi il codice che ho scritto è da ultra-principiante…sicuramente si può fare qualcosa di meglio!