How to play music in Metro using file URL mechanism - c#

I need to play Music Library files using file URL, that I will set to MediaPlayer object in a XAML c# object.
I constructed URI as followed
StorageFile file = await KnownFolders.MusicLibrary.GetFileAsync(track.Id);
return new Uri("file:///" + file.Path);
URI looks like this: streamingUri = {file:///C:/Users/user/Music/04 - A Train Makes A Lonely Sound.mp3}
I need URL based scheme to play so that I can reuse same logic for web streaming too.
How do I make this work?

Take a look at
this sample. It should give you some ideas of how to do media playback from file.
While I notice you are saying you need a URI-based, you should use a stream for a local file. The only part you need to extract is a call to set the MediaElement's Source. You can just make a function with 2 overrides and it should be relatively clean.
So, for a web stream:
void SetMediaElementSource(Uri webStreamUri)
{
MyMediaElement.Source = webStreamUri;
}
And for a local file:
void SetMediaElementSource(StorageFile file)
{
var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
MyMediaElement.SetSource(stream, file.ContentType);
}

Related

Accessing and creating/deleting files in Pictures Library?

I am attempting to create a file in the Pictures Library as documented in Microsofts UWP api.
The Pictures Library typically has the following path.
%USERPROFILE%\Pictures
I have enabled the Pictures library capability in the app manifest.
Like so:
File.WriteAllBytes("%USERPROFILE%/Pictures", fileData);
It returns:
DirectoryNotFoundException: Could not find a part of the path 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\HoloViewerVS.Debug_x86.jtth.jh\%USERPROFILE%\Pictures'
`
When I try using my username hard-coded, like so:
File.WriteAllBytes("jtth.jh/Pictures", fileData);
it returns the same DirectoryNotFound exception:
DirectoryNotFoundException: Could not find a part of the path 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\HoloViewerVS.Debug_x86.jtth.jh\jtth.jh\Pictures'`
So, how do you access the Pictures Library and write files to it? Clearly I must be missing something small here as the path its trying to access the pictures library at seems quite odd here.
I see it says how to 'Get the Pictures library.' using a StorageFolder:
public static StorageFolder PicturesLibrary { get; }
But I'm not sure how to add files to this folder variable like the way I'm doing it using the file write.
Can I do it the way I am trying to do it, or do I need to jump through StorageFolder and/or async hoops?
Example for clarification:
string imgName = currentFolderLoaded + "/" + temp.GetComponentInChildren<Text>().text;
//example imgName to enhance clairty
imgName = C:\dev\Users\jtth\Hololens\ProjectFolder\App\HoloApp\Data\myFiles\pics\example.png
//load image
byte[] fileData;
Texture2D tex = null;
fileData = File.ReadAllBytes(imgName);
tex = new Texture2D(2, 2);
tex.LoadImage(fileData);
//test hololens access
//previous attempt -> File.WriteAllBytes("%USERPROFILE%/Pictures", fileData);
//New attempt
AsStorageFile(fileData, imgName);
//Read Texture into RawImage component
ImgObject.GetComponent<RawImage>().material.mainTexture = tex;
//Enable component to render image in game
ImgObject.GetComponent<RawImage>().enabled = true;
Function:
private static async Task<StorageFile> AsStorageFile(byte[] byteArray, string fileName)
{
Windows.Storage.StorageFolder storageFolder = Windows.Storage.KnownFolders.PicturesLibrary;
Windows.Storage.StorageFile sampleFile = await storageFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
await Windows.Storage.FileIO.WriteBytesAsync(sampleFile, byteArray);
return sampleFile;
}
I'm checking the Photos app on the Hololens after running through this code and it doesn't seem to be creating the picture?
If you want your pictures showed in the Photos app on Hololens, actually you may need to save the pictures into CameraRoll folder.
But it seems like it cannot be directly saved, you may need to move the picture file as a workaround.
var cameraRollFolder = Windows.Storage.KnownFolders.CameraRoll.Path;
File.Move(_filePath, Path.Combine(cameraRollFolder, _filename));
Details please reference this similar thread.
It is because UWP applications work under isolated storage. Like the first example in your linked MSDN article says, do something like this:
StorageFolder storageFolder = KnownFolders.PicturesLibrary;
StorageFile file = await storageFolder.CreateFileAsync("sample.png", CreationCollisionOption.ReplaceExisting);
// Do something with the new file.
Plain File.Xxx() calls will be isolated to your application's own little world.

How to play mp3 music file from uri end with extension .mp4 in WinRT apps

I have web Uri like: http://123.456.769/music.mp4.
While I set MediaElement's Source with that uri, I got a media failed exception ("Could not open that video"),
But I can play this file, if download and rename it to "music.mp3";
How can play it without download?
Create a Stream via the Uri. You can use the RandomAccessStreamReference class.
var uriStreamReference = RandomAccessStreamReference.CreateFromUri(myUri);
var uriStream = await uriStreamReference.OpenAsync();
You can then set the source of your MediaElement via the SetSource method. You can also set the MIME type for mp4 audio.
myMediaElement.SetSource(uriStream, "audio/mp4");
If it's an mp3 whose filename is simply an mp4, switch to audio/mpeg.
Hope this helps and happy coding!

How to download and upload file to SkyDrive via Live Connect SDK

I have an app that I want to download & upload a simple .txt file with a URL inside. I have downloaded Live Connect SDK V5.4, referenced the documentation, but it appears that the documentation is incorrect. The sample code uses event handlers for when a download/upload is complete, but that no longer can be used in V5.4.
I have two methods, downURL & upURL. I have started working on downURL:
private async void downURL()
{
try
{
LiveDownloadOperationResult download = await client.DownloadAsync("URL.txt");
}
catch { }
}
I am not sure what I am suppose to use for the path, I put "URL.txt" for now, I've seen some examples with "/me/". Do I need this? The file does not need to be visible to the user, as the user can't really do anything with it, but it is vital for the app to work.
My question is how do I use the LiveDownloadOperationResult download to save the file to Isolated Storage Settings, get the text contents, and put that in a string? Also, if you know how to upload the file back up, the upload event handler looks the same (but without the Result variable).
This code help you download content a file which you want. It get content have format OpenXML
Here, "item.id" is Id of "URL.txt".
private async void downURL()
{
try
{
LiveDownloadOperationResult operationResult = await client.DownloadAsync(item.id + "/Content?type=notebook");
StreamReader reader = new StreamReader(operationResult.Stream);
string Content = await reader.ReadToEndAsync();
}
catch { }
}

Read audio file to stream with MediaPlayer (WPF)

I use MediaPlayer to play audio files
var mediaPlayer = new MediaPlayer();
mediaPlayer.Open(new Uri(s));
mediaPlayer.Play();
Sometimes I need to delete files that MediaPlayer is still playing.
I guess I have somehow read file to stream to be get free access to it in order to delete it. I mean i sthere way to read file to stream or I have to create some temp. file to play and in this case I can delete the original one or there are other options?
How to implement it?
Thank you!
Actually, when you call MediaPlayer.Open it reads in the file via a stream automatically. The problem is that the stream is still open when you try to delete the file.
MediaPlayer has a .Close method on it. Calling this will close the stream that's reading in the file.
here's the documentation on the MediaPlayer class so you can see what other methods are available to use: http://msdn.microsoft.com/en-us/library/system.windows.media.mediaplayer.aspx
EDIT: If you don't mind that the player stops playback when you call Close then you can just Close & then delete your file. If you do need playback to continue then you'll need a different approach.
If you're using Silverlight then you can just load the stream directly into a MediaElement:
var bytes = File.ReadAllBytes(#"c:\yourfile.ext");
var mStream = new MemoryStream(bytes);
mediaElement1.SetSource(mStream);
Sadly, WPF does not have the same stream support. I attempted to get a Uri for the MemoryStream by writing the stream into the resource pack. Though, i couldn't get it to playback correctly in my testing. I'll include my source that i had just in case you want to fiddle with it and maybe get it to work:
var bytes = File.ReadAllBytes(#"C:\Bill\TestWaveFiles\14043.wav");
MemoryStream packStream = new MemoryStream()
Package pack = Package.Open(packStream, FileMode.Create, FileAccess.ReadWrite);
Uri packUri = new Uri("bla:");
PackageStore.AddPackage(packUri, pack);
Uri packPartUri = new Uri("/MemoryResource", UriKind.Relative);
PackagePart packPart = pack.CreatePart(packPartUri, "Media/MemoryResource");
packPart.GetStream().Write(bytes, 0, bytes.Length);
var inMemoryUri = PackUriHelper.Create(packUri, packPart.Uri);
mediaElement1.LoadedBehavior = MediaState.Manual;
mediaElement1.Source = inMemoryUri;
mediaElement1.Play();
Another option is to simply make a copy of the file before you open it. that way you can always delete the original. Though, you could also just "mark" the file to be deleted. When the user is done playing the the file then you could close & delete it.
One additional option is to use a 3rd party library called BoxedApp. It seemingly will allow you to have a "Virtual File" that contains a memory stream. You could then get a Uri that points to this virtual file and load it into the media player. Look at this answer by
user1108125 to see how to use this BoxedApp library (which i've never used). https://stackoverflow.com/a/8587166/1721136

can't Get stream of mp3 file in wp7 application

i'm building a wp7 application for a game using silverlight & XNA
i have an mp3 file called "Punch1.mp3" (Build action : resource ) stored inside a folder called "SoundEffects" inside the project folder
and i want to play the file using this code
StreamResourceInfo info;
Uri myuri = new Uri("/SoundEffects/Punch1.mp3", UriKind.Relative);
info = App.GetResourceStream (myuri);
punch1 = SoundEffect.FromStream(info.Stream ) ;
punch is defined in the code here :
public static SoundEffect punch1;
the problem is that it raises a nullreference exception in the third line claiming that info is null
and that's true in the debugging mode , i found that the resource stream info is null
i think this is because the it can't read the file although the uri is correct
You can try two things
- Clean and rebuild the project
- Try appending project name in URI "/PhoneApp1;component/SoundEffects/Punch.mp3"
Since you're using the XNA assembly anyway, you can use TitleContainer.OpenStream instead (with a relative URI) and have the audio file build set as Content.
I agree with Haris Haqsan that your URI string is bad.
Uri myuri = new Uri("/PhoneBoxing;component/SoundEffects/Punch1.mp3", UriKind.Relative);
But you should also consider switching to using content files instead embedding them at resources as it can help your application start up time. Depending on the amount of files we are talking about, it can make a big difference.
Set your Build Action to content and your code should look like:
FileStream stream = new FileStream("/SoundEffects/Punch1.mp3", FileMode.Open, FileAccess.Read);
in the following code :
Uri myuri = new Uri("/SoundEffects/Punch1.mp3", UriKind.Relative);
info = App.GetResourceStream (myuri);
punch1 = SoundEffect.FromStream(info.Stream ) ;
SoundEffect.FromStream() expects a wave file stream not an MP3 as shown here : http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.audio.soundeffect.fromstream.aspx .
so solution to find a mp3 > wav convertor or just find another way to load mp3 to WP7
considering the picture this is normal URI in normal cases can't evaluate expression of isfile .
I was experiencing the same issue on my machine, the InvalidOperationException is a little confusing. All I had to do was re-encode the wav file to the specifications listed on MSDN.
After I did that, it worked perfectly.

Categories