MediaStreamSource is not applying Bitrate Assigned to Media Encoding Profile - c#

I'm using media composition to preview videos and to generate streams. I pass a MediaEncoding Profile in which the video container I am assigning the bitrate has to apply when previewing. But it's not working. Here's the code:
MediaEncodingProfile profile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD720p);
profile.Video.Bitrate = 1000000; // Any Bitrate
var stream = VideoComposition.GenerateMediaStreamSource(profile);
videoPlayer.SetMediaStreamSource(stream);

By testing, there is no effect in the MediaStreamSource when we assign MediaEncodingProfile.Video.Bitrate in your scenario.
You could use Windows.Media.Transcoding APIs to transcode video files from one format to another to show the effect of assigning bitrate.
Please check the following code as a sample:
private MediaComposition VideoComposition;
private MediaStreamSource mediaStreamSource;
private StorageFile destination;
……
private async void button_Click(object sender, RoutedEventArgs e)
{
var picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
picker.FileTypeFilter.Add(".mp4");
Windows.Storage.StorageFile pickedFile = await picker.PickSingleFileAsync();
if (pickedFile == null)
{
return;
}
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
destination = await localFolder.CreateFileAsync("destination.mp4",CreationCollisionOption.ReplaceExisting);
MediaEncodingProfile profile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD720p);
MediaTranscoder transcoder = new MediaTranscoder();
profile.Video.Bitrate = 50000; // Any Bitrate
PrepareTranscodeResult prepareOp = await
transcoder.PrepareFileTranscodeAsync(pickedFile, destination, profile);
if (prepareOp.CanTranscode)
{
var transcodeOp = prepareOp.TranscodeAsync();
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;
}
}
}
private async void TranscodeComplete(IAsyncActionWithProgress<double> asyncInfo, AsyncStatus asyncStatus)
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () => {
var stream = await destination.OpenAsync(Windows.Storage.FileAccessMode.Read);
videoPlayer.SetSource(stream, destination.ContentType);
});
}
You could delete the destination file if you do not want to save the file.

Related

Want to Open multiple audio files and play them in UWP

I want to open multiple audio files in UWP using the FileOpenPicker but I am getting an error that I cant Cannot Convert. How can I fix this?
And if this is fixed, will all the audio files play in order or all at the same time?
public MainPage()
{
this.InitializeComponent();
}
MediaSource media_source;
MediaPlayer media_player;
public async System.Threading.Tasks.Task OpenfileAsync()
{
var filePicker = new Windows.Storage.Pickers.FileOpenPicker();
filePicker.FileTypeFilter.Add(".mp3");
filePicker.FileTypeFilter.Add(".mp4");
filePicker.FileTypeFilter.Add(".ogg");
filePicker.FileTypeFilter.Add(".wav");
filePicker.FileTypeFilter.Add(".wma");
filePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.MusicLibrary;
StorageFile file = await filePicker.PickSingleFileAsync();
if (file != null)
{
media_source = MediaSource.CreateFromStorageFile(file);
media_player = new MediaPlayer();
media_player.Source = media_source;
mediaPlayerElement.SetMediaPlayer(media_player);
media_player.Play();
}
}
private async void Select_track_Click(object sender, RoutedEventArgs e)
{
await OpenfileAsync();
}
public async System.Threading.Tasks.Task OpenMultipleAsync()
{
var filePicker = new Windows.Storage.Pickers.FileOpenPicker();
filePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.MusicLibrary;
filePicker.FileTypeFilter.Add(".mp3");
filePicker.FileTypeFilter.Add(".mp4");
filePicker.FileTypeFilter.Add(".ogg");
filePicker.FileTypeFilter.Add(".wav");
filePicker.FileTypeFilter.Add(".wma");
filePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.MusicLibrary;
StorageFile file = await filePicker.PickMultipleFilesAsync();
if (file != null)
{
media_source = MediaSource.CreateFromStorageFile(file);
media_player = new MediaPlayer();
media_player.Source = media_source;
mediaPlayerElement.SetMediaPlayer(media_player);
media_player.Play();
}
}
private async void playlist_Click(object sender, RoutedEventArgs e)
{
await OpenMultipleAsync();
}
I am getting the error at StorageFile file = await filepicker.PickmultiplefilesAsync();
The FileOpenPicker.PickMultipleFilesAsync method has the following signature:
IAsyncOperation<IReadOnlyList<StorageFile>> PickMultipleFilesAsync()
In contrast to PickFileAsync it returns a IReadOnlyList<StorageFile>, so you will actually get a list of multiple files the user selected. You should update the code like this:
var files = await filePicker.PickMultipleFilesAsync();
foreach (var file in files)
{
if (file != null)
{
media_source = MediaSource.CreateFromStorageFile(file);
media_player = new MediaPlayer();
media_player.Source = media_source;
mediaPlayerElement.SetMediaPlayer(media_player);
media_player.Play();
}
}
This solution will play all the sounds at once. For one by one playback you can use #touseefbsb solution :-) .
for playing a list of files its best that you use MediaPlaybackList
Also you only need to set the SuggestedStartLocation once, and when you use PickMultipleFilesAsync() you get a List of files returned so you need that iterate through that list to get all files and add them to your MediaPlaybackList
Modify your OpenMultipleAsync method like this :
public async System.Threading.Tasks.Task OpenMultipleAsync()
{
var filePicker = new Windows.Storage.Pickers.FileOpenPicker();
filePicker.FileTypeFilter.Add(".mp3");
filePicker.FileTypeFilter.Add(".mp4");
filePicker.FileTypeFilter.Add(".ogg");
filePicker.FileTypeFilter.Add(".wav");
filePicker.FileTypeFilter.Add(".wma");
filePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.MusicLibrary;
_mediaPlaybackList = new MediaPlaybackList();
var files = await filePicker.PickMultipleFilesAsync();
foreach (var file in files)
{
var mediaPlaybackItem = new MediaPlaybackItem(MediaSource.CreateFromStorageFile(file));
_mediaPlaybackList.Items.Add(mediaPlaybackItem);
}
_mediaPlayer = new MediaPlayer();
_mediaPlayer.Source = _mediaPlaybackList;
mediaPlayerElement.SetMediaPlayer(_mediaPlayer);
}
More details about MediaPlaybackItem can be seen here
and to answer 'will these media files play together at the same time or one after the other' : they will play one after the other in a row, that is the purpose if MediaPlaybackList, it supports gapless playback for playlists.

UWP File Management

Why does saving a file fail so often on UWP?
I open and read the contents of a specified file when the application is initially launched (with the help of a BackgroundWorker). Then when the application is suspending I try to save new content to the same file, however this results almost always in the following exception:
Unable to remove the file to be replaced. (Exception from HRESULT: 0x80070497)
My loading method:
private async static void SymbolLoader_DoWork(object sender, DoWorkEventArgs e)
{
IStorageItem file = null;
if (!UseDefault)
{
var folder = await StorageFolder.GetFolderFromPathAsync(SavePath);
file = await folder.TryGetItemAsync(FileName);
}
if (file == null)
{
file = await Package.Current.InstalledLocation.GetFileAsync(#"Assets\Default.txt");
}
var text = await FileIO.ReadTextAsync((IStorageFile)file);
Data = DoSomething(text);
}
My OnSuspending method:
private async void OnSuspending(object sender, SuspendingEventArgs e)
{
var tries = 0;
var maxTries = 10;
var deferral = e.SuspendingOperation.GetDeferral();
while (tries < maxTries)
{
var completed = await Saver.Save();
if (completed)
break;
else
{
tries++;
await Task.Delay(TimeSpan.FromSeconds(0.1));
}
}
deferral.Complete();
}
Save method:
public static async Task<bool> Save()
{
//some formatting etc.
var folder = await StorageFolder.GetFolderFromPathAsync(SavePath);
var file = await folder.CreateFileAsync(FileName, CreationCollisionOption.ReplaceExisting);
try
{
await FileIO.WriteLinesAsync(file, lines);
return true;
}
catch(Exception e)
{
return false;
}
}
It is critical that the data is saved, which is why I "solved" the problem by trying to save the file multiple times with some delay. However my solution, presented in the OnSuspending method, does not seem like the correct way to do this.
What is the correct approach? Thanks in advance!

How to open and auto capture camera using MediaCapture class

we are trying to automatically capture an image from the webcam using MediaCapture class. We are trying to create an application which opens the camera, waits for a moment and captures the image in front of it without someone to tap the screen to capture. we tried using LowLagPhotoCapture class but does not work as desired. Sample code -
async private void InitMediaCapture()
{
MediaCapture _mediaCapture = new MediaCapture();
await _mediaCapture.InitializeAsync();
_displayRequest.RequestActive();
PreviewControlCheckIn.Source = _mediaCapture;
await _mediaCapture.StartPreviewAsync();
await Task.delay(500);
CaptureImage();
}
async private void CaptureImage()
{
storeFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync ("TestPhoto.jpg",CreationCollisionOption.GenerateUniqueName);
ImageEncodingProperties imgFormat = ImageEncodingProperties.CreateJpeg();
await _mediaCapture.CapturePhotoToStorageFileAsync(imgFormat, storeFile);
await _mediaCapture.StopPreviewAsync();
}
Any info would be great, thanks in advance for the help.
I have completed your provided code and achieved your requirement. Please refer to the following code. Please note that you should declare camera and the microphone capabilities in your Universal Windows Platform (UWP) app's package manifest to access certain API.
async private void InitMediaCapture()
{
_mediaCapture = new MediaCapture();
var cameraDevice = await FindCameraDeviceByPanelAsync(Windows.Devices.Enumeration.Panel.Back);
var settings = new MediaCaptureInitializationSettings { VideoDeviceId = cameraDevice.Id };
await _mediaCapture.InitializeAsync(settings);
_displayRequest.RequestActive();
PreviewControl.Source = _mediaCapture;
await _mediaCapture.StartPreviewAsync();
var picturesLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
_captureFolder = picturesLibrary.SaveFolder ?? ApplicationData.Current.LocalFolder;
await Task.Delay(500);
CaptureImage();
}
async private void CaptureImage()
{
var storeFile = await _captureFolder.CreateFileAsync("PreviewFrame.jpg", CreationCollisionOption.GenerateUniqueName);
ImageEncodingProperties imgFormat = ImageEncodingProperties.CreateJpeg();
await _mediaCapture.CapturePhotoToStorageFileAsync(imgFormat, storeFile);
await _mediaCapture.StopPreviewAsync();
}
private static async Task<DeviceInformation> FindCameraDeviceByPanelAsync(Windows.Devices.Enumeration.Panel desiredPanel)
{
// Get available devices for capturing pictures
var allVideoDevices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
// Get the desired camera by panel
DeviceInformation desiredDevice = allVideoDevices.FirstOrDefault(x => x.EnclosureLocation != null && x.EnclosureLocation.Panel == desiredPanel);
// If there is no device mounted on the desired panel, return the first device found
return desiredDevice ?? allVideoDevices.FirstOrDefault();
}
The photo will be saved to Pictures library. And I have upload the code sample to github. Please check!

Read Barcode in an WP8.1 app with ZXing

Im currently writing my first app for WP8.1. The app just need to scan a barcode.
public async void ScanBarcodeAsync(Windows.Storage.StorageFile Afile)
{
WriteableBitmap bitmap;
BitmapDecoder decoder;
using (IRandomAccessStream str = await Afile.OpenReadAsync())
{
decoder = await BitmapDecoder.CreateAsync(str);
bitmap = new WriteableBitmap(Convert.ToInt32(decoder.PixelWidth),
Convert.ToInt32(decoder.PixelHeight));
await bitmap.SetSourceAsync(str);
}
ZXing.BarcodeReader reader = new BarcodeReader();
/*reader.Options.PossibleFormats = new ZXing.BarcodeFormat[]
{
ZXing.BarcodeFormat.CODE_128,
ZXing.BarcodeFormat.CODE_39
};*/
reader.Options.TryHarder = true;
reader.AutoRotate = true;
var results = reader.Decode(bitmap);
if (results != null)
{
edtBarcode.Text = results.Text;
}
else
{
edtBarcode.Text = "Error";
}
}
The file for this method is created this way
async void StartCapture()
{
var cameraID = await GetCameraID(Windows.Devices.Enumeration.Panel.Back);
MediaCaptureInitializationSettings settings = new MediaCaptureInitializationSettings();
settings.PhotoCaptureSource = Windows.Media.Capture.PhotoCaptureSource.VideoPreview;
settings.StreamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.Video;
settings.AudioDeviceId = string.Empty;
settings.VideoDeviceId = cameraID.Id;
captureManager = new MediaCapture(); //Define MediaCapture object
await captureManager.InitializeAsync(settings); //Initialize MediaCapture and
var focusSettings = new FocusSettings();
focusSettings.AutoFocusRange = AutoFocusRange.Macro;
focusSettings.Mode = FocusMode.Auto;
focusSettings.WaitForFocus = true;
focusSettings.DisableDriverFallback = false;
captureManager.VideoDeviceController.FocusControl.Configure(focusSettings);
captureManager.SetPreviewRotation(VideoRotation.Clockwise90Degrees);
capturePreview.Source = captureManager; //Start preiving on CaptureElement
await captureManager.StartPreviewAsync(); //Start camera capturing
}
async private void Capture_Photo_Click(object sender, RoutedEventArgs e)
{
//Create JPEG image Encoding format for storing image in JPEG type
ImageEncodingProperties imgFormat = ImageEncodingProperties.CreateJpeg();
// create storage file in local app storage
if (ImageIndex > 0)
{
StorageFile delFile = await ApplicationData.Current.LocalFolder.GetFileAsync("Photo" + Convert.ToString(ImageIndex - 1) + ".jpg");
await delFile.DeleteAsync();
}
file = await ApplicationData.Current.LocalFolder.CreateFileAsync("Photo" + Convert.ToString(ImageIndex++) + ".jpg", CreationCollisionOption.ReplaceExisting);
// take photo and store it on file location.
await captureManager.CapturePhotoToStorageFileAsync(imgFormat, file);
//// create storage file in Picture Library
//StorageFile file = await KnownFolders.PicturesLibrary.CreateFileAsync("Photo.jpg",CreationCollisionOption.GenerateUniqueName);
// Get photo as a BitmapImage using storage file path.
bmpImage = new BitmapImage();
bmpImage.CreateOptions = BitmapCreateOptions.None;
bmpImage.UriSource = new Uri(file.Path);
ImageTaken = true;
Frame.Navigate(typeof(MainPage));
Frame.Navigate(typeof(MainPage));
}
I dont get an error running this code. But the result from ZXing is always null. The ScanBarcodeAsync-Function is directly run after taking the picture. The image the app takes is not sharp. Can this cause the problem?
Im happy to get any suggestions to solve my problem.

FileSavePicker for Audio file is not working in Windows Phone 8.1 Universal Apps

I tried this below code, the audio file is saving but it shows 0 bytes, I tried a lot if any one know about this please help me...
WP8.1 Universal Apps
Code in Mainpage.cs:
private async void pick_Click(object sender, RoutedEventArgs e)
{
string path = #"Assets\Audio\DeviPrasad.mp3";
StorageFolder folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
StorageFile file = await folder.GetFileAsync(path);
var st =await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
var size = st.Size;
FileSavePicker savePicker = new FileSavePicker();
//savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
savePicker.SuggestedSaveFile = file;
savePicker.FileTypeChoices.Add("MP3", new List<string>() { ".mp3" });
savePicker.ContinuationData.Add("SourceSound", path);
savePicker.SuggestedFileName = "DeviPrasad";
savePicker.PickSaveFileAndContinue();
}
internal async void ContinueFileOpenPicker(FileSavePickerContinuationEventArgs e)
{
var file = e.File;
var ff= file.Properties;
if(file!=null)
{
CachedFileManager.DeferUpdates(file);
await FileIO.WriteTextAsync(file, file.Name);
FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(file);
}
}
Code In App.xaml.cs:
protected async override void OnActivated(IActivatedEventArgs args)
{
var root = Window.Current.Content as Frame;
var mainPage = root.Content as MainPage;
if (mainPage != null && args is FileSavePickerContinuationEventArgs)
{
mainPage.ContinueFileOpenPicker(args as FileSavePickerContinuationEventArgs);
}
}
The FileSavePicker will not help you to write or copy the content of the file to the destination.
Actually, I think you just simply copy the following code from somewhere but don't exactly know what it is doing.
await FileIO.WriteTextAsync(file, file.Name);
This is to write things to the file, and seems it is from a sample which handles txt file. For your case, we need to do the following things:
Add the source file path to ContinuationData in pick_Click event. Change the code to:
savePicker.ContinuationData.Add("SourceSound", file.Path);
Read the source file path and destination file in ContinueFileOpenPicker to write the content as below:
var file = e.File;
string soundPath = (string)e.ContinuationData["SourceSound"];
//var ff = file.Properties;
if (file != null)
{
CachedFileManager.DeferUpdates(file);
StorageFile srcFile = await StorageFile.GetFileFromPathAsync(soundPath);
await srcFile.CopyAndReplaceAsync(file);
FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(file);
}

Categories