Condividi tramite


Il presente articolo è stato tradotto automaticamente.

Per l'utente

Per l'utente - Codifica di video mediante Microsoft Expression Encoder 3 SDK

Antonio Martino

In uno dei miei scene di film preferiti di tutti i tempi, w. Clark Griswold (Chevy Chase in “ Natale vacanze ”) Ottiene intercettato nel suo attic mentre nascondere Natale presenta. Per mantenere a caldo, egli dons guanti rosa, un cappello verde e un fur marrone rubare estratta da un seno polveroso. In fondo il seno egli individua filmati dal suo gioventù e passa ora guardando li (con intervento nel suo occhi), utilizzando un vecchio proiettore Pellicola.

Filmati ormai un modo molto da allora, ma gli utenti ancora affrontare uno degli stessi problemi: Come visualizzare il filmato ad amici e familiari Siti come YouTube, Vimeo e Facebook rendere la condivisione semplice; ma in 100-plus MB al minuto di video ad alta definizione, il recupero di dati in tali siti può essere un'attività molto tempo. È probabile, il dispositivo portatile, il sistema di gioco o home theater media center anche non riprodurre il file. Per risolvere questi problemi, è necessario convertire il video in un altro formato. Questo processo è noto come codifica.

Informazioni su Expression Encoder

Microsoft video codifica strumento, Expression Encoder 3, fa parte della famiglia di prodotti per la creazione di interfacce utente accattivanti per applicazioni desktop e Web Expression. Expression Encoder è disponibile in versioni gratuite e pagate; la versione pagata parte di Expression Studio 3 Suite (599 dollari) ed Expression Web 3 Suite ($ 149). Download gratuito non supporta la codifica a flusso continuo di Silverlight o H.264 using o video H.264 video come origine, ma consentono di codificare file Windows Media Video e ha un bel SDK. Molti degli esempi di codice in questo articolo richiedono 
version pagamento del programma; tuttavia, tutti gli esempi di codice verranno generato in versione gratuita di SDK. Durante l'esecuzione, verrà visualizzato un InvalidMediaException o un FeatureNotAvailableException sufficiente.

Se non si è pronti per acquistare Expression Suite, è possibile iniziare con Expression Encoder scaricando la versione gratuita da microsoft.com/expression . È anche disponibile come parte di sottoscrizione MSDN o Visual Studio Professional con MSDN Premium Subscription. Tenere presente che 149 dollari per applicazione software con questo set di funzionalità di codifica video professionale, vasta gamma di formati di input e output supportati destinazioni rubare un relativo. Soluzioni di codifica video simili possono costi upward di € 3.000.

Indipendentemente dalla versione prescelto, sarà necessario installare QFE 3 codificatore. Aggiunge il supporto per altri tipi di file e periferiche di input, migliora le prestazioni di determinate situazioni e include correzioni minori. Il programma di installazione QFE sono reperibili nella pagina Expression Encoder nel sito Microsoft Expression Web.

Formati supportati

Sono supportati i formati video inpui:

  • Windows Media Video (WMV)
  • Video DVD (VOB)
  • MPEG (mpg, MPEG)
  • Audio Video Interleave (avi)
  • Microsoft Digital Video Recording (dvr-ms)

La versione pagata aggiunge i seguenti formati (e pochi altri formati):

  • MPEG-4 (mp4, .m4v)
  • QuickTime (mov)
  • AVC HD (.mts)
  • Video di dispositivi mobili (.3gp, .3g2)

Per la maggior parte, Expression Encoder supporta qualsiasi file multimediale che può riprodurre. Se si desidera anche ulteriori file di supporto (ed essere in grado di riprodurli in Windows Media Player), è possibile installare un pacchetto di codec, ad esempio K Lite Codec Pack (codecguide.com) o Community Combined Codec Pack (cccp project.net). Entrambe sono basate sul progetto open source ffdshow e verrà aggiunto il supporto per i file codificati VP6 Flash (.flv), video H.264 nel contenitore Matroska (.mkv) e file video Ogg (.ogg).

La versione gratuita di Expression Encoder supporta solo Microsoft VC-1 come un codec output. Tuttavia, questo ancora consente codificare video per Silverlight (velocità in singolo bit solo), Xbox 360, Zune e Zune HD. Inoltre, il codec VC-1 non è Nessun slouch; la compressione è una buona (se non migliori in determinate situazioni) come H.264. L'aggiornamento per la versione pagato consente output Silverlight Smooth Streaming video (multi-velocità in bit) nonché H.264, significa che è possibile codificare video riproducibile il lettore Flash iPhone, PS3, (versione 10 supporta H.264/.mp4) e innumerevoli altre periferiche.

Codifica 101

Il supporto di determinate periferiche di output richiede modificando alcune impostazioni del profilo video, sarà necessario comprendere i concetti di base di codifica video. Re-Encoding video è effettivamente il processo di decompressione di un video e re-compressing utilizzando un altro codec o modificare manualmente gli attributi quali dimensioni, proporzioni o frequenza fotogrammi. Sebbene esistano metodi di compressione senza perdita di dati, sta utilizzati raramente poiché i file video risultanti sono ancora molto grandi. Per ridurre la quantità di spazio necessaria per memorizzare (e quindi trasferire) del video, pertanto un algoritmo, noto come un codec viene utilizzato per comprimere e decomprimere il video. Il flusso video compresso viene quindi archiviato in base a specifiche noto come un contenitore (ad esempio WMV o MP4). Codec e contenitori sono spesso non esclusivo un contratto, H.264 è il codec più comune trovato nel contenitore MP4, potrebbe essere utilizzati altri codec.

Velocità in bit, espressa in kilobit al secondo definisce la quantità di dati da utilizzare per archiviare il video compresso. Riducendo la velocità in bit indica il codificatore per comprimere il video a una velocità più elevata, effetti negativi sulla qualità video. Esistono diversi modi per indicare il codificatore come determinare la velocità in bit del video. Il modo più semplice consiste nell'utilizzare una velocità in costante bit (CBR), che impone il codificatore per utilizzare la stessa quantità di dati per ogni secondo di video. Una velocità in bit variabile (VBR) può essere utilizzato per indicare il codificatore quale dovrebbe essere la velocità in bit totale del file, ma il codificatore può aumentare o diminuire la velocità in bit in base alla quantità di dati necessari per una determinata sezione del video. Velocità in bit vincolata variabile è simile a VBR non vincolata, tranne che offrono non solo una velocità in bit media da utilizzare, ma anche una velocità in bit massima non può essere superato.

Velocità in bit vincolata variabile è utile durante la codifica video Silverlight Smooth Streaming. Consente di verificare che la velocità in bit non superi la larghezza di banda del client, imporre al client di richiedere un flusso di qualità inferiore. CBR e VBR indicano il livello di compressione da utilizzare specificando una dimensione di file video in generale.

In alternativa, è possibile indicare il codificatore utilizzare VBR basata sulla qualità. Invece di specificare le dimensioni complessive del video, è possibile specificare una percentuale di qualità (ovvero la quantità di dati) dell'origine video per mantenere decompressi. Richiede meno dati per mantenere una buona qualità per un'animazione, ad esempio, più per una natura o video inseriti in azione. Pertanto, se si dispone di un'origine di alta qualità e si desidera convertire l'origine in un altro formato e mantenere la qualità ottimale, è consigliabile utilizzare VBR basata sulla qualità. Queste definizioni sono solo suggerimento di the iceberg ma sono fondamentali per la scelta delle impostazioni di output. Puoi trovare altre definizioni di codifica in questo articolo si applicano a esempi di codice.

Utilizzando il SDK

Per seguire gli esempi di codice, sarà necessario utilizzare un video di qualità buona. Se non si dispone di posizione attorno ad alta risoluzione video, è possibile ottenere alcuni video HD interessante da microsoft.com/windows/windowsmedia/musicandvideo/hdvideo/contentshowcase.aspx . Utilizzerò il video Adrenaline urgenti come origine per questi esempi.

Dopo l'installazione di Expression Encoder 3, creare un nuovo progetto di Visual Studio C# Console Application. Aggiungere riferimenti a Microsoft.Expression.Encoder.dll e Microsoft.Expression.Encoder.Utilities.dll situato \Programmi Files (x 86) \Microsoft Expression\Encoder 3\SDK. Sarà inoltre necessario aggiungere un riferimento a WindowsBase, si trovano nella scheda .NET della finestra di dialogo Aggiungi riferimento. Molte delle classi utilizzate saranno nello spazio dei nomi Microsoft.Expression.Encoder così aggiungere using istruzione per esso.

Il primo elemento per creare un'istanza è un oggetto MediaItem. Il costruttore MediaItem accetta una stringa come unico parametro al costruttore. Passare il percorso del file che si sta utilizzando come origine per il progetto di codifica:

MediaItem src = new MediaItem(@"C:\WMdownloads\AdrenalineRush.wmv");

Creazione di un oggetto MediaItem accetta solo un secondo o due. il SDK sta effettuando una notevole quantità di lavoro dietro le quinte, tuttavia, la raccolta di informazioni sull'origine video, quali l'altezza, larghezza, frequenza fotogrammi (frequenza che singole immagini devono essere visualizzate sullo schermo) e la durata. Informazioni sul flusso audio vengono raccolte anche in questo momento.

Quindi si crea un'istanza della classe processo (che ha solo un costruttore senza parametri) e aggiungere le MediaItem all'elenco delle MediaItems. La classe processo funge da gestore per i formati di output desiderato (noto come profili):

Job job = new Job();
job.MediaItems.Add(src);

Ora è necessario indicare il processo i profili da utilizzare durante la codifica audio e video, la soluzione più semplice consiste nell'utilizzare uno dei profili definiti nell'interfaccia utente. Per creare un video Zune HD, ad esempio, è possibile utilizzare l'impostazione predefinita VC1ZuneHD:

job.ApplyPreset(Presets.VC1ZuneHD);

Infine, specificare una directory di output e avviare il processo di codifica:

job.OutputDirectory = @"C:\EncodedFiles";
job.Encode();

Il file Program.cs dovrebbe essere simile a di Figura 1.

Figura 1 creazione un video per Zune HD

using Microsoft.Expression.Encoder;

namespace TestApp
{
  class Program
  {
      static void Main(string[] args)
      {
          MediaItem src = new MediaItem
              (@"C:\WMdownloads\AdrenalineRush.wmv");
          Job job = new Job();
          job.MediaItems.Add(src);
          job.ApplyPreset(Presets.VC1ZuneHD);
          job.OutputDirectory = @"C:\EncodedFiles";
          job.Encode();
      }
  }
}

C'è un'ultima cosa da fare prima di eseguire l'applicazione: Se si utilizza una versione a 64 bit di Windows, sarà necessario modificare il progetto da generare per x 86. Nella barra dei menu di Visual Studio, selezionare proprietà (nome progetto) e del progetto. Nella finestra di dialogo visualizzata, selezionare la scheda generazione e cambiare la piattaforma di destinazione da “ Any CPU ” “ x 86. ”

Si è ora pronti per eseguire l'applicazione e creare un video riproducibile in Zune HD. Il processo di codifica richiederà alcuni minuti per completare ed è molto dispendiosa a livello di CPU. Vantaggi di codifica video vengano calcolate attività parallele, in modo che i computer multicore sono qui un grande vantaggio.

Expression Encoder include inoltre le preimpostazioni per la codifica ai servizi in linea quali YouTube, Vimeo e Facebook. video 720p registrato dalla fotocamera digitale Lumix Panasonic DMC-ZS3 consuma circa 110 MB al minuto del video registrato. Conversione di video tramite YouTube HD preimpostazione (anche 720p) riduce il video a solo 16 MB. Questo rende più efficiente per caricare e archiviare localmente. Conversione di un file mp4 rende compatibili con molti altri programmi di modifiche video.

Impostazioni personalizzate

Per manualmente produrre lo stesso output come il VC1ZuneHD preimpostato, sarà necessario utilizzare un codice simile a di Figura 2 per impostare il codice profiles.For audio e video in Figura 2 per compilare, sarà necessario aggiungere i riferimenti Microsoft.Expression.Encoder.Utilities e System.Drawing. Aggiungere inoltre istruzioni using per Microsoft.Expression.Encoder.Profiles e System.Drawing. Il OutputFormat essenzialmente specifica il contenitore per il file di output. Dico essenzialmente perché la codifica per Silverlight funziona solo leggermente diverso (come verrà illustrato tra breve).

Figura 2 video e audio OPS per Zune HD

MediaItem src = new MediaItem(@"C:\WMdownloads\AdrenalineRush.wmv");

src.OutputFormat = new WindowsMediaOutputFormat();

src.OutputFormat.VideoProfile = new AdvancedVC1VideoProfile();
src.OutputFormat.VideoProfile.Bitrate = new 
    VariableConstrainedBitrate(1000, 1500);
src.OutputFormat.VideoProfile.Size = new Size(480, 272);
src.OutputFormat.VideoProfile.FrameRate = 30;
src.OutputFormat.VideoProfile.KeyFrameDistance = new TimeSpan(0, 0, 4);
src.OutputFormat.AudioProfile = new WmaAudioProfile();
src.OutputFormat.AudioProfile.Bitrate = new 
    VariableConstrainedBitrate(128, 192);
src.OutputFormat.AudioProfile.Codec = AudioCodec.WmaProfessional;
src.OutputFormat.AudioProfile.BitsPerSample = 24;


Job job = new Job();
job.MediaItems.Add(src);
job.OutputDirectory = @"C:\EncodedFiles";
job.Encode();

Il VideoProfile specifica il codec video da utilizzare con le impostazioni dettagliate da utilizzare per la codifica. Analogamente, il AudioProfile specifica il codec da utilizzare insieme alle relative impostazioni. Quando si crea un VariableConstrainedBitrate, il primo parametro specifica la velocità in bit media e il secondo parametro specifica la velocità in bit massima. L'impostazione della dimensione indica la casella che dovrebbe contenere video codificato. La dimensione corretta ripartizione del urgenti Adrenaline video è effettivamente 480 x 272 per mantenere le proporzioni, ma se immesso 480 x 480 il video risultante ancora sarebbe 480 x 272.

Figura 2 del KeyFrameDistance proprietà fa riferimento a un concetto di codifica video che non ancora illustrato. L'il funzionamento di codifica più video consiste nel memorizzare solo le modifiche da una cornice a quella successiva, anziché l'intera immagine per ogni fotogramma video. I fotogrammi chiave sono i frame che contengono l'intera immagine. Questo codice crea fotogrammi chiave ogni quattro secondi. I fotogrammi chiave vengono creati automaticamente quando sono presenti modifiche grandi nel video, ad esempio una modifica della scena, ma è necessario anche creare intervalli predefiniti per supportare la ricerca all'interno del filmato durante la riproduzione.

Opzione di Silverlight Streaming

Smooth Streaming di Silverlight passa dinamicamente la velocità in bit del file multimediale riprodotto in base alle condizioni correnti della rete. Un progetto Smooth Streaming è costituita da singoli video archiviati in file .ismv, nonché file di metadati .ism e .ismc supportano la riproduzione Smooth Streaming.

Per creare un progetto Silverlight Smooth Streaming, devono essere apportate più modifiche. Innanzitutto, modificare il KeyFrameDistance per due secondi. Il video verrà riprodotti se il KeyFrameDistance viene lasciato a quattro secondi, ma è possibile notare hiccups nella riproduzione quando il lettore passa bitrates. Lettore Silverlight richiederà il video in blocchi di due secondi, la riproduzione è più coerenza se vi è un fotogramma chiave all'inizio di ogni richiesta. È inoltre necessario aggiungere la seguente riga:

src.OutputFormat.VideoProfile.SmoothStreaming = true;

L'impostazione SmoothStreaming su true indica il codificatore video .ismv nei file di output e creare i file .ism e ismc. Con solo una velocità in bit non è realmente un progetto flusso continuo, pertanto per creare più output bitrates, è necessario aggiungere più flussi di VideoProfile. Eseguire questa operazione utilizzando codice simile a di Figura 3.

Figura 3 di Aggiunta uniforme di Silverlight Streaming

MediaItem src = new MediaItem(@"C:\WMdownloads\AdrenalineRush.wmv");
src.OutputFormat = new WindowsMediaOutputFormat();

src.OutputFormat.VideoProfile = new AdvancedVC1VideoProfile();
src.OutputFormat.VideoProfile.KeyFrameDistance = new TimeSpan(0, 0, 2);
src.OutputFormat.VideoProfile.SmoothStreaming = true;
src.OutputFormat.VideoProfile.Streams.Clear();
src.OutputFormat.VideoProfile.Streams.Add(new StreamInfo(new 
    VariableConstrainedBitrate(2000, 3000), new Size(1280, 720)));
src.OutputFormat.VideoProfile.Streams.Add(new StreamInfo(new 
    VariableConstrainedBitrate(1400, 1834), new Size(848, 476)));
src.OutputFormat.VideoProfile.Streams.Add(new StreamInfo(new 
    VariableConstrainedBitrate(660, 733), new Size(640, 360)));

src.OutputFormat.AudioProfile = new WmaAudioProfile();
src.OutputFormat.AudioProfile.Bitrate = new 
    VariableConstrainedBitrate(128, 192);
src.OutputFormat.AudioProfile.Codec = AudioCodec.WmaProfessional;
src.OutputFormat.AudioProfile.BitsPerSample = 24;

Job job = new Job();
job.MediaItems.Add(src);
job.OutputDirectory = @"C:\EncodedFiles";
job.Encode();

Qui il codice specifica tre dimensioni per 
encode e bitrates diversi. Qualità ottimale, le dimensioni video devono ridurre come si riduce la velocità in bit. Quando si specifica il proprio bitrates, è possibile utilizzare le impostazioni di IIS Smooth Streaming nell'interfaccia utente di 3 di Expression Encoder. Si noti che non è possibile ottenere la qualità dalla codifica un video a una risoluzione superiore a quella del file di origine. E solo senso codificare a una velocità in bit superiore rispetto al file di origine se si utilizza un metodo di compressione più debole. Se il SDK è stato in grado di determinare la velocità in bit del file di origine, sarà presente nelle proprietà di profilo SourceVideo del MediaItem:

int bitrate = ((ConstantBitrate)src.SourceVideoProfile.Bitrate).Bitrate;

Se il SDK Impossibile ottenere velocità in bit del file di origine, è possibile ottenere una stima molto stretta in base alla dimensione del file. Ecco la formula:

Velocità in bit approssimativo in kb/s = (dimensioni del file in kilobyte * 8 / video durata in secondi)-velocità in bit audio in kb/s

È possibile utilizzare la classe System.IO.FileInfo per ottenere la dimensione del file di origine e il SDK per ottenere la durata (proprietà MediaItem.FileDuration) ed eventualmente la velocità in bit audio. Se non si conosce la velocità in bit audio, utilizzare 128 o 160 per stimare (la maggior parte delle bitrates audio sono tra 64 e 192); è inoltre possibile ottenere la velocità in bit audio nella finestra Proprietà di Windows Media Player (premere ALT per visualizzare il menu, quindi il file | proprietà).

Monitoraggio stato

Perché un processo di codifica può richiedere ore, è utile poter visualizzare l'avanzamento di codifica. il SDK fornisce un modo semplice per controllare il processo di codifica tramite un evento che è possibile aggiungere un gestore per:

job.EncodeProgress += new EventHandler<EncodeProgressEventArgs>(OnProgress);

Aggiungere un metodo per gestire l'evento seguente:

static void OnProgress(object sender, EncodeProgressEventArgs e)
{
  Console.Clear();
  Console.WriteLine((100 * (e.CurrentPass - 1) + e.Progress) / e.TotalPasses + "%");
}

Codifica Multi-pass è un concetto nuovo rilevante nel codice di esempio. Quando si utilizza una velocità in bit variabile per la codifica, il processo viene eseguito in due passaggi, noti come passa . Durante il primo passaggio del video di origine viene analizzato per determinare le parti più complesse e potrebbero trarre vantaggio da una velocità in bit maggiore. Durante il secondo passaggio, il video viene codificato utilizzando le informazioni ottenute durante il primo passaggio. Pertanto, se si utilizza una velocità in bit costante, non è necessario utilizzare le proprietà della classe EncodeProgressEventArgs CurrentPass o TotalPasses.

Combinazione di video

Se si desidera codificare solo una parte di un video o unire più video, il SDK fornisce supporto. Per modificare l'inizio e interrompere ora per un elemento di origine multimediale, è possibile modificare le proprietà del clip. Per codificare solo i primi sei secondi di un video, utilizzare codice simile:

src.Sources[0].Clips[0].StartTime = new TimeSpan(0);
src.Sources[0].Clips[0].EndTime = new TimeSpan(0, 0, 6);

Per aggiungere altri video come file di origine, è possibile aggiungere altri video alla proprietà di MediaItem le origini. Questo verrà codificare i file di origine in ordine di un singolo file di output:

MediaItem src = new MediaItem(@"C:\WMdownloads\AdrenalineRush.wmv");
src.Sources.Add(new Source(@"C:\WMdownloads\Video2.wmv"));

Live Encoding

Expression Encoder supporta inoltre la codifica da origini live, ad esempio una webcam. Il concetto (e codice) è simile alla codifica di file video, ma si utilizza un diverso insieme di classi. Questi sono disponibili nello spazio dei nomi Microsoft.Expression.Encoder.Live.

La prima classe da utilizzare è LiveJob. LiveJob funziona come Encoder.Job—it gestisce le operazioni di codifica il video. In uno scenario reale il OutputFormat è una proprietà di LiveJob anziché un oggetto MediaItem (che non è necessario). La creazione di un'istanza di un oggetto LiveJob verrà cercare periferiche di input video collegate al computer e popolare le proprietà VideoDevices e AudioDevices. È quindi possibile utilizzare come un'origine di input per il codificatore. Figura 4 viene illustrato un esempio.

Figura 4 di codifica Video Live

using (LiveJob job = new LiveJob())
{
  LiveDevice videoDevice = job.VideoDevices[0];
  LiveDevice audioDevice = job.AudioDevices[0];
  LiveDeviceSource liveSource = job.AddDeviceSource(videoDevice, 
      audioDevice);
  job.ActivateSource(liveSource);
  WindowsMediaBroadcastOutputFormat outputFormat = new 
     WindowsMediaBroadcastOutputFormat();
  outputFormat.BroadcastPort = 8080;
  job.OutputFormat = outputFormat;
  Console.WriteLine("Press enter to stop encoding...");
  job.StartEncoding();
  Console.ReadLine();
  Console.WriteLine("Stopping");
  job.StopEncoding();
}

Verrà avviato una sessione di codifica live tramite una webcam (se si dispone di una connessione) e broadcast sul computer locale sulla porta 8080. Per visualizzare la codifica live, aprire Windows Media Player e scegliere File | Apri URL e immettere mms://localhost:8080. Dopo alcuni buffer, verrà visualizzato il video dalla webcam, anche se è possibile notare un ritardo di 20-30 secondi per il tempo che necessario per la codifica e il flusso di trasporto. È possibile utilizzare potenzialmente questo video come origine per i servizi Windows Media o dei servizi multimediali di IIS per la trasmissione al mondo.

Altri strumenti

Se non si è certi che le impostazioni di codifica scelto fornirà la qualità dell'output è necessario, l'interfaccia utente di Expression Encoder 3 fornisce una funzionalità utile denominate A / A/b. Consente di codificare cinque secondi del video circostante la posizione di riproduzione corrente. Il video codificato verrà visualizzata a schermo diviso con il video di origine (vedere di Figura 5), in modo da potere confrontare facilmente la qualità del video codificato con l'originale.

Figura 5 A / A/b in Expression Encoder 3

image: A/B Compare in Expression Encoder

È quindi possibile salvare le impostazioni correnti come un set di impostazioni definite dall'utente facendo clic su Modifica | Salva impostazioni correnti come impostazioni predefinite. L'impostazione predefinita verrà memorizzato come file XML, che è possibile utilizzare con il SDK:

job.ApplyPreset(@"C:\WMdownloads\NewPreset.xml");

Se si utilizza già pensando semplice sarebbe per automatizzare il processo di conversione video con un'applicazione console, esaminiamo il modulo di PowerShell Convert Media per Expression Encoder, disponibile all'indirizzo convertmedia.codeplex.com . Questo modulo PowerShell esegue il wrapping di Expression Encoder SDK, che fornisce un'interfaccia della riga di comando codifica senza scrivere alcun codice. Come con tutti i progetti CodePlex, è open source.

È auspicabile che ora comprendere la terminologia di base relativa alla codifica video e prendere decisioni motivate sui quali codec e la velocità in bit da utilizzare. È inoltre sapere come utilizzare Expression Encoder 3 SDK per codificare video per destinazioni specifiche quali Xbox 360, iPhone e Silverlight, nonché di live streaming video. Pertanto non attendere di essere intercettato nel attic come Clark w. Griswold per realizzare il valore di home video e ricordi dimenticati. È possibile convertirli in un formato che renderà accessibile al mondo.

Adam Miller è un software engineer per Nebraska globale nel Lincoln, Neb. È possibile seguire blog del Miller all'indirizzo blog.milrr.com.

Grazie all'esperto tecnica seguente per la revisione di questo articolo: Ben Rush