|
Spesso capita di vedere dei filmati che sono la registrazione di una
sessione windows; dalla prima volta che ho visto un filmato del genere, subito
mi sono chiesto come realizzare una cosa simile; in effetti concettualmente non
deve essere poi così difficile visto che è possibile, a livello di programma,
salvare un' immagine del desktop. Ne salviamo una ogni decimo di secondo e l'
unione di queste immagini diventa poi il filmato: da internet è possibile
trovare delle procedure anche in Delphi per creare un filmato da una serie di
immagini ed il gioco è fatto. Certo, solo che il problema è che le prestazioni
sono veramente inacettabili, per non parlare poi della dimensione del filmato
risultante, veramente esagerata anche per filmati di 4 o 5 minuti. Bene ... poi
ieri mi sono imbattuto in un articolo all' indirizzo
http://www.codeproject.com/vb/net/CaptureScreenAsVideo.asp in cui si parla
appunto di un programma del genere creato in pochissime righe di codice
utilizzando Windows Media Encoder 9. Bene, mi sono scaricato Windows Media
Encoder 9 all' url
http://www.microsoft.com/windows/windowsmedia/9series/encoder/default.aspx
ed una volta installato, sono andato nella cartella di installazione (di default
è la cartella C:\Programmi\Windows Media Components\Encoder) e tra gli
eseguibili ho trovato un tale wmenc.exe che, una volta lanciato, mi presenta una
bella finestra di scelta in cui trovo addirittura l' opzione "Capture Screen"
che consente di realizzare la telecamerina tanto desiderata. Bene, però il mio
cruccio non è il programma in sè ma come realizzarlo. Sono partito dall'
indirizzo
Creating an Encoding Application
che descrive come realizzare degli applicativi che interagiscano con la
tecnologia Windows Media Encoder 9. Tra i sottoparagrafi c' è appunto anche
quello che tratta della registrazione di una sessione in un filmato. Come nel
caso di moltre altre tecnologie Microsoft, anche questa è implementata tramite
le interface: infatti se apriamo Delphi (stò usando Delphi 7), Project -->
Import Type Library nell' elenco troviamo ben 5 typelibrary differenti relative
al Windows Media Encoder 9. Per fare quello che vogliamo fare ci basta (e
avanza) la prima typelibrary ossia Windows Media Encoder (Version 1.0).
Bene, importiamola (tolgo l' eventuale spunta nella voce in basso "generate
component wrapper" poichè non voglio generare i componenti relativi alle
interfacce) con un click su "Create Unit". Otteniamo la unit di import di nome
WMEncoderLib_TLB. Includendo tale unit nel nostro programma possiamo
costruire la nostra applicazione. Bene, un paio di pulsanti su una form (uno per
iniziare la registrazione e l' altro per fermarla), un pò di righe di codice ed
il gioco è fatto: di seguito il sorgente completo (con un pò di documentazione
ed approfondimenti)
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls,
WMEncoderLib_TLB;
type
TFrmScreenCam = class(TForm)
btStartRecording: TButton;
btStopRecording: TButton;
procedure btStartRecordingClick(Sender: TObject);
procedure btStopRecordingClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
FrmScreenCam: TFrmScreenCam;
Encoder: IWMEncoder2;
implementation
{$R *.DFM}
procedure TFrmScreenCam.btStartRecordingClick(Sender: TObject);
var
SrcGrp: IWMEncSourceGroup2;
SrcGrpColl: IWMEncSourceGroupCollection;
SrcVid: IWMEncVideoSource2;
SrcAud: IWMEncAudioSource;
ProColl: IWMEncProfileCollection;
Pro: IWMEncProfile;
i: Integer;
lLength: Longint;
Descr: IWMEncDisplayInfo;
Attr: IWMEncAttributes;
File_: IWMEncFile;
InputColl: IWMEncInputCollection;
begin
//
// Creazione di un oggetto WMEncoder
Encoder := CoWMEncoder.Create;
// Definiamo la collezione dei gruppi sorgente relativi all' oggetto WMEncoder
//appena creato, inserendone uno di nome SG_1
SrcGrpColl := Encoder.SourceGroupCollection;
SrcGrp := (SrcGrpColl.Add('SG_1') as IWMEncSourceGroup2);
// Aggiungiamo una fonte video ed una audio al gruppo sorgente SG_1 appena inserito.
SrcVid := (SrcGrp.AddSource(WMENC_VIDEO) as IWMEncVideoSource2);
SrcAud := (SrcGrp.AddSource(WMENC_AUDIO) as IWMEncAudioSource);
// Definiamo le caratteristiche delle due fonti (video e audio) appena aggiunte al
//gruppo sorgente SG_1: la fonte video è la sessione Windows e la fonte audio è il
//dispositivo audio di default
SrcVid.SetInput('ScreenCap://ScreenCapture1', '', '');
SrcAud.SetInput('Device://Default_Audio_Device', '', '');
// Quando si effettua la creazione di un filmato ci sono vari parametri che determinano
//le caratteristiche del file video: tutte queste caratteristiche possono essere
//salvate nei cosidetti file di profilo che, nello standard, hanno estensione .prx.
//Questi file possono essere creati, letti e modificati tramite il programma
//WMProEdt.exe che si trova nella cartella di installazione di Windows Media Encoder 9
//(che di default è la cartella C:\Programmi\Windows Media Components\Encoder).
//Nella sottocartella Profiles della cartella di installazione di Windows Media Encoder 9
//si trovano 6 file di profilo. Questi sono i profili che vengono presi in considerazione
//dal componente Encoder quando crea l' oggetto collezione di profili come di seguito
//eseguendo Encoder.ProfileCollection:
//Encoder.ProfileCollection restituisce una collezione di profili (vengono utilizzati
//di default i profili memorizzati nella sottocartella Profiles della cartella di
//installazione di Windows Media Encoder 9). Tramite WMProEdt.exe si possono creare
//nuovi profili personalizzati che salvati nella cartella Profiles incrementano la
//collezione; è da notare che si può modificare la cartella da usare come contenitore
//dei profili: l' oggetto Encoder.ProfileCollection si popola infatti dei profili
//definiti dai file .prx presenti nella cartella specificata dalla sua proprietà
//ProfileDirectory. Se settiamo
//Encoder.ProfileCollection.ProfileDirectory := 'c:\pippo\cartella_profili',
//allora la collezione verrà creata in base ai file .prx presenti nella cartella
//'c:\pippo\cartella_profili'.
//Di seguito nome del file e nome del profilo corrispondente memorizzato
//(relativamente alla sottocartella Profiles)
(*schi.prx
Screen Video High (CBR)
schia.prx
Screen Video/Audio High (CBR)
sclo.prx
Screen Video (CBR)
scloa.prx
Screen Video/Audio
scmed.prx
Screen Video Medium (CBR)
scmeda.prx
Screen Video/Audio Medium (CBR)
*)
ProColl := Encoder.ProfileCollection;
//numero dei profili
lLength := ProColl.Count;
//MessageBoxW(0, pWideChar(ProColl.ProfileDirectory), 'ciao', 0);
//exit;
//l' elenco dei profili salvati come file .prx è presente di default nella cartella
//C:\Programmi\Windows Media Components\Encoder\Profiles:
//li si può aprire ognuno con l' eseguibile
//C:\Programmi\Windows Media Components\Encoder\WMProEdt.exe
//per vedere il nome e le caratteristiche; per la registrazione che dobbiamo fare
//useremo il profilo 'Screen Video/Audio High (CBR)' salvato nel file schia.prx
//navigo nella collezione dei profili alla ricerca di quello che mi interessa
for i := 0 to lLength - 1 do
begin
Pro := ProColl.Item(i); //profilo i-esimo
// if Pro.Name = 'Windows Media Video 8 for Local Area Network (384 Kbps)' then
if Pro.Name = 'Screen Video/Audio High (CBR)' then
begin
//assegnao al gruppo sorgente SG_1 il profilo 'Screen Video/Audio High (CBR)'
//(memorizzato nel profilo schia.prx presente nella sottocartella Profiles
SrcGrp.Set_Profile(Pro);
break;
end;
end;
//Non serve a nulla ma dato che ci siamo inseriamo anche un pò
//di proprietà relativamente al file video che andiamo a creare:
//tali valori saranno visibili da dentro Windows Media Player con
//File->Proprietà->Content
Descr := Encoder.DisplayInfo;
Descr.Title := 'Sessione Windows';
Descr.Author := 'Carlo Pasolini (cdpasop@virgilio.it)';
Descr.Copyright := 'nessun copyright';
// Descr.Rating := 'Rating information';
Descr.Description := 'Registrazione di una sessione Windows' + #13#10 +
'utilizzando Windows Media Encoder 9;' + #13#10#13#10 +
'http://utenti.lycos.it/carlpasolini';
// Specifico le caratteristiche del file su cui andrò a salvare la registrazioen
File_ := Encoder.File_;
File_.LocalFileName := GetCurrentDir + '\OutputFile.wmv';
// Inizio la registrazione.
Encoder.Start();
end;
procedure TFrmScreenCam.btStopRecordingClick(Sender: TObject);
begin
//
//l' oggetto Encoder dispone della proprietà RunState che definisce in che stato
//di esecuzione si trova l' oggetto stesso (in esecuzione, in pausa, stoppato, etc..
//l' elenco dei possibili valori è il seguente (sono autoesplicativi)
(*
WMENC_ENCODER_STARTING; //sta partendo la registrazione
WMENC_ENCODER_RUNNING; //sta registrando
WMENC_ENCODER_PAUSED; //è in pausa (usando il metodo Pause)
WMENC_ENCODER_STOPPING; //la registrazione si sta arrestando
WMENC_ENCODER_STOPPED; //è fermo
WMENC_ENCODER_END_PREPROCESS;
WMENC_ENCODER_PAUSING; //sta andando in pausa
*)
if (Encoder.RunState = WMENC_ENCODER_RUNNING) then
begin
// Chiudo la registrazione.
Encoder.Stop();
//elimino l 'oggetto Encoder
Encoder := nil;
end;
//ho usato il metodo Stop per terminare la registrazione come, nel caso dell' altro
//pulsante avevo usato il metodo Start.
end;
end.
sorgente (N.B. è necessario il Windows Media Encoder 9)
|