Transcodificar arquivos de mídia

Podes usar o Windows. Media.Transcoding APIs para transcodificar ficheiros de vídeo de um formato para outro.

Transcodificação é a conversão de um ficheiro de media digital, como um ficheiro de vídeo ou áudio, de um formato para outro. Isto é normalmente feito através da decodificação e depois recodificação do ficheiro. Por exemplo, pode converter um ficheiro Windows Media para MP4 para que possa ser reproduzido num dispositivo portátil que suporte formato MP4. Ou pode converter um ficheiro de vídeo em alta definição para uma resolução mais baixa. Nesse caso, o ficheiro recodificado pode usar o mesmo codec do ficheiro original, mas teria um perfil de codificação diferente.

Selecionar ficheiros de origem e destino

A forma como a sua aplicação determina os ficheiros de origem e destino para transcodificação depende da sua implementação. Este exemplo utiliza um FileOpenPicker e um FileSavePicker para permitir ao utilizador escolher um ficheiro de origem e um de destino.

var openPicker = new Windows.Storage.Pickers.FileOpenPicker();

// Initialize the picker with the window handle (required for WinUI desktop apps).
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(App.MainWindow);
WinRT.Interop.InitializeWithWindow.Initialize(openPicker, hwnd);

openPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
openPicker.FileTypeFilter.Add(".wmv");
openPicker.FileTypeFilter.Add(".mp4");

StorageFile source = await openPicker.PickSingleFileAsync();

var savePicker = new Windows.Storage.Pickers.FileSavePicker();

WinRT.Interop.InitializeWithWindow.Initialize(savePicker, hwnd);

savePicker.SuggestedStartLocation =
    Windows.Storage.Pickers.PickerLocationId.VideosLibrary;

savePicker.DefaultFileExtension = ".mp4";
savePicker.SuggestedFileName = "New Video";

savePicker.FileTypeChoices.Add("MPEG4", new string[] { ".mp4" });

StorageFile destination = await savePicker.PickSaveFileAsync();

Criar um perfil de codificação multimédia

O perfil de codificação contém as definições que determinam como o ficheiro de destino será codificado. É aqui que tens o maior número de opções ao transcodificar um ficheiro.

A classe MediaEncodingProfile fornece métodos estáticos para criar perfis de codificação pré-definidos:

Métodos para criar perfis de codificação apenas de áudio

Método Profile
CreateAlac Áudio Apple Lossless Audio Codec (ALAC)
CreateFlac Áudio gratuito em Lossless Audio Codec (FLAC)
CreateM4a Áudio AAC (M4A)
CreateMp3 Áudio MP3
CreateWav Áudio WAV
CreateWma Windows Media Audio (WMA)

Métodos para criar perfis de codificação de áudio / vídeo

Método Profile
CreateAv1 Vídeo AOMedia Video 1 (AV1)
CreateAvi AVI
CreateHevc Vídeo de Codificação de Vídeo de Alta Eficiência (HEVC), também conhecido como vídeo H.265
CreateMp4 Vídeo MP4 (vídeo H.264 mais áudio AAC)
CreateVp9 Vídeo do VP9
CreateWmv Vídeo Windows Media (WMV)

O código seguinte cria um perfil para vídeo MP4.

MediaEncodingProfile profile =
    MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD720p);

O método estático CreateMp4 cria um perfil de codificação MP4. O parâmetro deste método fornece a resolução alvo para o vídeo. Neste caso, VideoEncodingQuality.hd720p significa 1280 x 720 píxeis a 30 fotogramas por segundo. ("720p" significa 720 linhas de varrimento progressivas por frame.) Os outros métodos para criar perfis predefinidos seguem todos este padrão.

Em alternativa, pode criar um perfil que corresponda a um ficheiro multimédia existente usando o método MediaEncodingProfile.CreateFromFileAsync . Ou, se souberes as definições exatas de codificação que queres, podes criar um novo objeto MediaEncodingProfile e preencher os detalhes do perfil.

Transcodifica o ficheiro

Para transcodificar o ficheiro, crie um novo objeto MediaTranscoder e chame o método MediaTranscoder.PrepareFileTranscodeAsync. Passe o ficheiro de origem, o ficheiro de destino e o perfil de codificação. Depois chama o método TranscodeAsync no objeto PrepareTranscodeResult que foi devolvido da operação de transcodificação assíncrona.

MediaTranscoder transcoder = new MediaTranscoder();

PrepareTranscodeResult prepareOp = await
    transcoder.PrepareFileTranscodeAsync(source, destination, profile);

if (prepareOp.CanTranscode)
{
    var transcodeOp = prepareOp.TranscodeAsync();

    transcodeOp.Progress +=
        new AsyncActionProgressHandler<double>(TranscodeProgress);
    transcodeOp.Completed +=
        new AsyncActionWithProgressCompletedHandler<double>(TranscodeComplete);
}
else
{
    switch (prepareOp.FailureReason)
    {
        case TranscodeFailureReason.CodecNotFound:
            System.Diagnostics.Debug.WriteLine("Codec not found.");
            break;
        case TranscodeFailureReason.InvalidProfile:
            System.Diagnostics.Debug.WriteLine("Invalid profile.");
            break;
        default:
            System.Diagnostics.Debug.WriteLine("Unknown failure.");
            break;
    }
}

Responder ao progresso da transcodificação

Pode registar eventos para responder quando o progresso do TranscodeAsync assíncrono muda. Estes eventos fazem parte do framework de programação assíncrona para aplicações Windows e não são específicos da API de transcodificação.

void TranscodeProgress(IAsyncActionWithProgress<double> asyncInfo, double percent)
{
    // Display or handle progress info.
}

void TranscodeComplete(IAsyncActionWithProgress<double> asyncInfo, AsyncStatus status)
{
    asyncInfo.GetResults();
    if (asyncInfo.Status == AsyncStatus.Completed)
    {
        // Display or handle complete info.
    }
    else if (asyncInfo.Status == AsyncStatus.Canceled)
    {
        // Display or handle cancel info.
    }
    else
    {
        // Display or handle error info.
    }
}