I'm trying to Get a Auto Next method i've tried using a Index Counter but I think I misunderstand how to properly set a list using the FilePicker
The code for the FilePicker is following :
public async void pick_Click_1(object sender, RoutedEventArgs e)
{
List<StorageFile> fileList = new List<StorageFile>();
var fop = new FileOpenPicker();
fop.FileTypeFilter.Add(".mp3");
fop.FileTypeFilter.Add(".mp4");
fop.FileTypeFilter.Add(".avi");
fop.FileTypeFilter.Add(".wmv");
fop.ViewMode = PickerViewMode.List;
pickedFileList = await fop.PickMultipleFilesAsync();
// add the picked files to our existing list
fileList.AddRange(pickedFileList);
foreach (StorageFile file in pickedFileList)
{
Playlist.Items.Add(file);
var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
videoMediaElement.SetSource(stream, file.ContentType);
}
videoMediaElement.Play();
The Current method i have for switching tracks|Videos
private async void itemclicked(object sender, ItemClickEventArgs e)
{
var file = e.ClickedItem as StorageFile;
if (file != null)
{
var stream = await file.OpenReadAsync();
videoMediaElement.SetSource(stream, file.ContentType);
}
}
Empty Event im trying to use to do this.
private void Element_MediaEnded(object sender, RoutedEventArgs e)
{
}
I've looked threw all the Microsoft Sample's. Issue Being They use the Mediaplayerelement += Mediaplayer And im using the MediaElement
The Answers Im looking for Can be A Resolution to my problem or assisting me in better understanding how to globally set the source of the mediaplayer using the Current or new list from the picker, Im new to all this and trying to grasp everything better Thank you!
I ended up taking Tousee's advice to seem's he's my mentor at this stage, I used the MediaplayerElement and mediaPLaybacklist's which made life Easier. And almost instantly fixed my problem.
Related
I am learning UWP, and am more familiar with Windows.Forms.
I have two buttons to upload files through my application to the server (btnUploadPrice is one of the two). To get the existing location of the file and store that info, i looked up how things are different in UWP compared to the Windows.Forms style and used these Microsoft pages as a template:
https://learn.microsoft.com/en-us/uwp/api/windows.storage.storagefile
https://learn.microsoft.com/en-us/uwp/api/Windows.Storage.Pickers.FileOpenPicker
Here is my button code:
private void btnUploadPrice_Click(object sender, RoutedEventArgs e)
{
//open file dialog and store name until save button pressed.
FileOpenPicker f = new FileOpenPicker();
StorageFile price = await f.PickSingleFileAsync();
f.SuggestedStartLocation = PickerLocationId.Desktop;
f.ViewMode = PickerViewMode.Thumbnail;
if (price != null)
{
// Store file for future access
Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.Add(price);
}
}
await f.PickSingleFileAsync() is underlined with the following error:
The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.
My issue is that this is almost a copy/paste from Microsoft, and it's giving me an error that doesn't make sense, because it is an Async method, it says it right in the name of the method.. PickSingleFileAsync
What am i missing?
await can only be used inside an async method. Just change your method signature to make it async:
private async void btnUploadPrice_Click(object sender, RoutedEventArgs e)
{
// your code
}
So I was trying to loop Background music in my UWP App, I have a class called soundControl that handles music and sounds like this:
public class soundControl
{
private static MediaElement loop = new MediaElement();
public static async void stopLoop()
{
loop.Stop();
}
public static async void loadLoopTimeBG()
{
Windows.Storage.StorageFolder folder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync(#"Assets\Sounds");
Windows.Storage.StorageFile file = await folder.GetFileAsync("battle.wav");
var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
loop.AutoPlay = false;
loop.SetSource(stream, file.ContentType);
loop.IsLooping = true;
}
public static void loopTimeBG()
{
loop.Play();
}
And whenever I want to play this music I call :
soundControl.loadLoopTimeBG();
soundControl.loopTimeBG();
the problem is the it plays just one time and stops and I have no Idea why
I tried another approach like:
loop.MediaEnded += mediaEnded;
and the event handler like this:
private static void mediaEnded(object sender, RoutedEventArgs e)
{
loop.Position = TimeSpan.Zero;
loop.Play();
}
it also didn't work and when debugging it doesn't even triger the mediaEnded event when music is complete.
Any help here would be most appreciated.
Thanks
MediaPlayer
Windows.Media.Playback.MediaPlayer is the recommended player for UWP that does not require to be in the XAML visual tree.
Its API is very similar to MediaElement:
private static MediaPlayer _mediaPlayer = new MediaPlayer();
public static async Task PlayUsingMediaPlayerAsync()
{
Windows.Storage.StorageFolder folder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync(#"Assets");
Windows.Storage.StorageFile file = await folder.GetFileAsync("Click.wav");
_mediaPlayer.AutoPlay = false;
_mediaPlayer.Source = MediaSource.CreateFromStorageFile(file);
_mediaPlayer.MediaOpened += _mediaPlayer_MediaOpened;
_mediaPlayer.IsLoopingEnabled = true;
}
private static void _mediaPlayer_MediaOpened(MediaPlayer sender, object args)
{
sender.Play();
}
You can even display the visuals of a MediaPlayer in XAML using MediaPlayerElement.
MediaPlayer allows for even more advanced playback scenarios using the MediaPlaybackList with support for looping, shuffle and gapless playback.
mediaElement.SetPlaybackSource(mediaPlaybackList);
MediaElement
After some digging around it seems that there are two issues.
MediaElement is XAML based control (in the Windows.UI.Xaml.Controls namespace), and it seems that it does not work properly until it is actually attached to a visual tree. Once you put the MediaElement on the page, it works as expected.
Secondly, loading source media does not happen immediately. Once you set the source, the control needs some time to actually load the media. For this purpose, you can use the MediaOpened event, that will notify you once it is really loaded.
So the code could look somewhat like this:
public static async Task LoadAndPlayAsync()
{
Windows.Storage.StorageFolder folder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync(#"Assets");
Windows.Storage.StorageFile file = await folder.GetFileAsync("Click.wav");
var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
loop.AutoPlay = false;
loop.SetSource(stream, file.ContentType);
//or simpler -
//loop.Source = new Uri("ms-appx:///Assets/Click.wav", UriKind.Absolute);
loop.MediaOpened += Loop_MediaOpened;
loop.IsLooping = true;
}
private static void Loop_MediaOpened(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
//play once the media is actually ready
loop.Play();
}
And before you call the LoadAndPlayAsync method, you have to attach the control somewhere (for example in a Grid):
GridContainer.Children.Add(SoundController.loop);
await SoundController.LoadAndPlayAsync();
I have created a sample project for my tests on my GitHub, you can check it out to see how I implemented it. The first button in the app attaches the control and the second loads and plays the sound. You can see that if you click only the second one, the sound does not play.
Trying to make some mediaplayer app. I put the mediaelement on wpf, wrote code to open media. But when i try to play it nothing is happening...
public void ContinueFileOpenPicker(FileOpenPickerContinuationEventArgs args)
{
if (args.Files.Count > 0)
{
foreach (StorageFile file in args.Files)
{
if (playlist.Contains(file.Path)) return;
playlist.Add(file.Path);
}
}
}
private void PlayButton_OnClick(object sender, RoutedEventArgs e)
{
MyMedia.Source = new Uri(playlist[0], UriKind.RelativeOrAbsolute);
MyMedia.Play();
}
Checked that mediaelement source isn't empty, it has a right value of path.
Try to rebuild like that, still doesnt work
private async void PlayButton_OnClick(object sender, RoutedEventArgs e)
{
var stream = await Playlist[0].OpenAsync(FileAccessMode.Read);
MyMedia.SetSource(stream, Playlist[0].ContentType);
MyMedia.Play();
}
Sorry it was my mistake.
Into my XAML, I forgot that the AutoPlay property of the MediaElement control was set to false.
This solve my problem.
Couple of things you need to watch out.
foreach (StorageFile file in args.Files)
{
if(playlist.Contains(file.Path))
{
return;// Dont return use continue. You will probably skip rest of the files.
}
playlist.Add(file.Path);
}
Add a Watch/Quickwatch to see if the new Uri(playlist[0], UriKind.RelativeOrAbsolute) points to a right location.
Setup source from storage file:
var storageFile = await KnownFolders.MusicLibrary.GetFileAsync("line.mp3");
var stream = await storageFile.OpenAsync(FileAccessMode.Read);
mediaElement.SetSource(stream, storageFile.ContentType);
mediaElement.Play();
I got it from this answer: How to play file from Library by MediaElement?
I have Nokia 730 and I want to make FlashLight work on it. But next code crash:
MediaCapture mc = new MediaCapture();
await mc.InitializeAsync();
if (mc.VideoDeviceController.TorchControl.Supported == true)
{
mc.VideoDeviceController.TorchControl.Enabled = true;
mc.VideoDeviceController.TorchControl.PowerPercent = 100; // here is crash
}
Any ideas? For some reasons solutions with older platforms (wp 7, wp8) doesn't works at all.
Fixed it by next code:
private async void Button_Click(object sender, RoutedEventArgs e)
{
// Initialize Media Capture and Settings Objects, mediaCapture declared global outside this method
var mediaCapture = new MediaCapture();
// Grab all available VideoCapture Devices and find rear device (usually has flash)
await mediaCapture.InitializeAsync();
var videoEncodingProperties = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Vga);
var videoStorageFile = await KnownFolders.VideosLibrary.CreateFileAsync("tempVideo.mp4", CreationCollisionOption.GenerateUniqueName);
await mediaCapture.StartRecordToStorageFileAsync(videoEncodingProperties, videoStorageFile);
await Task.Delay(TimeSpan.FromMilliseconds(500));
mediaCapture.VideoDeviceController.TorchControl.Enabled = true;
}
But for some reason I should wait 500 milliseconds before enable TorchControl. Can someone explain why?
According to this post it could help to try the following:
//to switch OFF flash light
mc.VideoDeviceController.FlashControl.Enabled = false;
//to switch ON flash light
mc.VideoDeviceController.FlashControl.Enabled = true;
This seems like a serious bug :
private void LayoutRoot_Drop(object sender, DragEventArgs e)
{
if ((e.Data != null) && (e.Data.GetDataPresent(DataFormats.FileDrop)))
{
FileInfo[] files = (FileInfo[])e.Data.GetData(DataFormats.FileDrop);
using (FileStream fileStream = files[0].OpenRead())
{
//Code reaching this point.
BitmapImage bmpImg = new BitmapImage();
bmpImg.ImageOpened += new EventHandler<RoutedEventArgs>(bmpImg_ImageOpened);
bmpImg.ImageFailed += new EventHandler<ExceptionRoutedEventArgs>(bmpImg_ImageFailed);
try
{
bmpImg.SetSource(fileStream);
}
catch
{
//Code dosen't reach here.
}
}
}
}
void bmpImg_ImageFailed(object sender, ExceptionRoutedEventArgs e)
{
//Code dosen't reach here.
}
void bmpImg_ImageOpened(object sender, RoutedEventArgs e)
{
//Code dosen't reach here.
}
I am experiencing a very strange behivour. Running this code on my computer, it works - when you drag a JPG on the LayoutRoot I can break inside bmpImg_ImageOpened().
But on a different machine it won't work - when dragging a JPG, I can break in the drop event but after SetSource() nothing happens : no exceptions are thrown, and non of the callbacks are invoked.
I tried it on another machine and it also didn't work.
edit:
On all of the machines, when adding an Image class and setting it's Source property to the bitmapImage, the image is shown fine. so I guess it's an issue with the callbacks. This is not enough because I still need those events.
I am banging my head here, what could it be ?
This is simply how Silverlight has always behaved. ImageOpened only fires if the image is downloaded and decoded (i.e. using Source). It does not fire when using SetSource. If you need access to the dimensions after loading your image either use WriteableBitmap for the PixelWidth and PixelHeight properties (instead of BitmapImage) or do something like:
img.Source = bmpImg;
Dispatcher.BeginInvoke(() =>
{
FakeImageOpened(); // Do logic in here
});
You have to set
bitmapImage.CreateOptions = BitmapCreateOptions.None;
Then the ImageOpened event is fired. This is because the default Options are CreateDelayed
Greetings
Christian
http://www.wpftutorial.net