I am developing an UWP app where you can download videos from YouTube and convert them to a mp3 file. My problem here is that the process of writing the bytes of the downloaded video to the created .mp4 file freezes the application although it is marked as async and all the necessary function calls are marked with the await keyword.
The following function has been assigned to the Click
attribute of the button:
private async void DownloadMp3File(object sender, RoutedEventArgs e)
{
string url = youtubeUrl.Text;
if (!string.IsNullOrEmpty(url) && url.Contains("youtube"))
{
string savePath = Environment.GetFolderPath(Environment.SpecialFolder.MyMusic);
StorageFolder storageFolder = KnownFolders.MusicLibrary;
var youTube = YouTube.Default; // starting point for YouTube actions
var video = await youTube.GetVideoAsync(url); // gets a Video object with info about the video
string videoPath = Path.Combine(savePath, video.FullName);
string mp3Path = Path.Combine(savePath, videoPath.Replace(".mp4", ".mp3"));
StorageFile videoFile = await storageFolder.CreateFileAsync(Path.GetFileName(videoPath), CreationCollisionOption.ReplaceExisting);
StorageFile mp3File = await storageFolder.CreateFileAsync(Path.GetFileName(mp3Path), CreationCollisionOption.ReplaceExisting);
await WriteBytesIntoVideoFile(videoFile, video).ConfigureAwait(false);
await ConvertMp4ToMp3(videoFile, mp3File);
await videoFile.DeleteAsync();
}
}
During debugging I managed to find out where the app would freeze. It freezes exactly during the time of writing the bytes of the YouTube video into the mp4 file.
The function WriteBytesIntoVideoFile
writes the bytes of the downloaded video into the created video file. before this implementation I used FileIO.WriteBytesAsync
but it is the same behaviour:
public async Task WriteBytesIntoVideoFile(StorageFile videoFile, YouTubeVideo downloadedVideo)
{
//await FileIO.WriteBytesAsync(videoFile, downloadedVideo.GetBytes());
var outputStream = await videoFile.OpenAsync(FileAccessMode.ReadWrite);
using (var dataWriter = new DataWriter(outputStream))
{
foreach (var byt in downloadedVideo.GetBytes())
{
dataWriter.WriteByte(byt);
}
await dataWriter.StoreAsync();
await outputStream.FlushAsync();
}
}
Finally the convert method which converts the mp4 to a mp3. It uses the MediaTranscoder
to achieve this.
public async Task ConvertMp4ToMp3(IStorageFile videoFile, IStorageFile mp3File)
{
MediaEncodingProfile profile = MediaEncodingProfile.CreateMp3(AudioEncodingQuality.Auto);
MediaTranscoder transcoder = new MediaTranscoder();
PrepareTranscodeResult prepareOp = await transcoder.PrepareFileTranscodeAsync(videoFile, mp3File, profile);
if (prepareOp.CanTranscode)
{
await 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;
}
}
}
Could anyone explain to me why the app freezes during the process of writing the bytes of the downloaded video to the mp4 file? Any help is appreciated.