UWP playing a .aif file with AudioGraph - c#

I am trying to play a sound with audio graph and it is failing on creating a file output node from a storage file. I have checked and the storage file is not null; The error I am getting is just unknown error and is of no help
Any ideas?
private async void HandlePlayCommand()
{
if (_audioGraph == null)
{
var settings = new AudioGraphSettings(AudioRenderCategory.Media);
var createResults = await AudioGraph.CreateAsync(settings);
if (createResults.Status != AudioGraphCreationStatus.Success) return;
_audioGraph = createResults.Graph;
var deviceResult = await _audioGraph.CreateDeviceOutputNodeAsync();
if(deviceResult.Status != AudioDeviceNodeCreationStatus.Success) return;
var outputNode = deviceResult.DeviceOutputNode;
StorageFile file = await GetStorageFiles();
var fileResult = await _audioGraph.CreateFileInputNodeAsync(file);
if (fileResult.Status != AudioFileNodeCreationStatus.Success) return;
var fileInputNode = fileResult.FileInputNode;
fileInputNode.AddOutgoingConnection(outputNode);
_audioGraph.Start();
}
}
private async Task<StorageFile> GetStorageFiles()
{
string CountriesFile = #"Assets\909_1.aif";
StorageFolder InstallationFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
StorageFile file = await InstallationFolder.GetFileAsync(CountriesFile);
return file;
}

By testing on my side, I'm afraid the .aif format currently is not supported by AudioGraph.CreateFileInputNodeAsync method. The formats sure to be supported that are .mp3,.wav,.wna,.m4a and so on. So the solution maybe change the audio files to other formats.
More details please reference the audio official sample.

Related

UWP, Access to the path is denied

I read some topic about file permission.
Someone said "App can access directories and files which the user manually selected with the FileOpenPicker or FolderPicker"
My codes are like as below:
public async void CsvParse()
{
var picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.FileTypeFilter.Add(".csv");
Windows.Storage.StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
string[] lines = File.ReadAllLines(file.Path);//this is where app stops working and gives error message.
}
}
Even when I choose file with FilePicker, it still gives me error. But when I choose file from appx folder, it works fine.
Is there a way to access other locations than app's folder?
try it this way:
public async void CsvParse()
{
var picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.FileTypeFilter.Add(".csv");
Windows.Storage.StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
IList<string> lines = await FileIO.ReadLinesAsync(file);//this is where app stops working and gives error message.
}
}
the StorageFile is the way you get access to a file. File.ReadAllLines(file.Path) you are passing a Filename, not the StorageFile but just the filepath is not enough for getting access

Uploading video to Azure Storage through Xamarin

I'm trying to upload a video file to my Azure Storage account. I've got it working with images, however trying to view an uploaded video gives the message "Video format or MIME-type is not supported". The video format is mp4.
I use the following code to upload:
public async Task UploadVideo(Stream video, string path)
{
var container = GetContainer("videos");
// Creates the container if it does not exist
await CreateContainer(container);
//Gets the file extension
string lastPart = path.Split('.').Last();
// Uploads the video to the blob storage
CloudBlockBlob videoBlob = container.GetBlockBlobReference(path);
videoBlob.Properties.ContentType = "video/" + lastPart;
await videoBlob.UploadFromStreamAsync(video);
}
Am I doing something wrong?
Thanks
Edit:
Here's the code I use to capture video on the phone:
private async Task TakeVideoButton_Clicked(object sender, EventArgs e)
{
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakeVideoSupported)
{
await DisplayAlert("No Camera", ":( No camera avaialble.", "OK");
return;
}
mediaFile = await CrossMedia.Current.TakeVideoAsync(new Plugin.Media.Abstractions.StoreVideoOptions
{
Name = "video.mp4",
Directory = "DefaultVideos",
});
if (mediaFile == null)
return;
await DisplayAlert("Video Recorded", "Location: " + mediaFile.Path, "OK");
videoStream = mediaFile.GetStream();
file.Dispose();
}
I just tested this on my phone instead of my emulator and it worked perfectly there, so I'm going to assume it's purely a emulator related issue.

How to access StorageFile from another method

So im making a windows store app that you select a file with one button, via file picker, then with another button it processes that file but im having trouble getting the selected file to processing method.
Since the Picker sets one of my text blocks to the path of the file to be displayed for the user i've tried using:
StorageFile file = await StorageFile.GetFileFromPathAsync(fullFilePath.Text);
But due to Windows RT limitations I just get access it denied from most locations
Any other suggestions on what to try?
First button click:
private async Task getFile()
{
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.ViewMode = PickerViewMode.List;
openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
openPicker.FileTypeFilter.Add(".txt");
StorageFile file = await openPicker.PickSingleFileAsync();
if (file != null)
{
fullFilePath.Text = file.Path;
}
else
{
updateStatus("File Selection cancelled.");
}
}
Second button start this but needs to use the file from above
private async Task processFile()
{
...
string content = await FileIO.ReadTextAsync(file);
...
}
Make the StorageFile a field in your class:
class MyClass
{
StorageFile m_pickedFile;
async Task GetFile()
{
// Setup the picker...
m_pickedFile = await openPicker.PickSingleFileAsync();
// Show the path to the user...
}
async Task ProcessFile()
{
if (m_pickedFile != null)
{
// now use m_pickedFile...
}
}
}

Json serializer - how to create a stream

public static async Task Store(ObservableCollection<Product> list)
{
Uri path = new Uri("ms-appx:///ListCollection.json");
var store = await StorageFile.GetFileFromApplicationUriAsync(path);
var stream = File.OpenWrite(store.Path);
var serialize = new DataContractJsonSerializer(typeof(ObservableCollection<Product>));
serialize.WriteObject(stream, list);
}
Ok this is the piece of code that I used to serialize a collection , works very well , no problem with it , but what I want and tried and no success. I created a JSON file in my project. I want to store and stream data to that file. I tried some methods but no success , how do I open a stream to a file that is currently in my project?
EDITED : Commented the code that was working and wrote what I intend to do. Thanks for support.
When I get to this line
var stream = File.OpenWrite(store.Path); it says that is inaccesible.
What I intend to do is serialize some data to a file called ListCollection.json that is emtpy , that file is project file. It might be the stream or it might be the file that gives me that error. No idea.
My guess is that your project file is located in the installation directory of your application and as far as I know you can't just write to that directory.
You would have to put a deployment action in your solution that writes the desired project file to the application data directory. There you should be able to write it.
I looked through some of the documentation and came accross this:
MSDN
The app's install directory is a read-only location.
I found a Link which makes use of a little hack or so it seems.
I am not sure if this will work if the application is deployed etc.
but you can try this to write the file.
I am not sure if you need a stream or not but feel free to comment:
private void Button_Click(object sender, RoutedEventArgs e)
{
ObservableCollection<string> list = new ObservableCollection<string>();
list.Add("Hallo");
list.Add("Welt");
Task t = Store(list);
}
public static async Task Store(ObservableCollection<string> list)
{
StorageFile file = await GetStorageFileFromApplicationUriAsync();
if (file == null)
{
file = await GetStorageFileFromFileAsync();
}
if (file != null)
{
await file.DeleteAsync();
await CreateFileInInstallationLocation(list);
}
}
private static async Task<StorageFile> GetStorageFileFromFileAsync()
{
StorageFile file = null;
if (file == null)
{
try
{
StorageFolder folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
file = await folder.GetFileAsync("ListCollection.json");
}
catch
{ }
}
return file;
}
private static async Task<StorageFile> GetStorageFileFromApplicationUriAsync()
{
StorageFile file = null;
try
{
Uri path = new Uri("ms-appx:///ListCollection.json");
file = await StorageFile.GetFileFromApplicationUriAsync(path);
}
catch
{ }
return file;
}
private static async Task CreateFileInInstallationLocation(ObservableCollection<string> list)
{
var pkg = Windows.ApplicationModel.Package.Current;
var installedLocationFolder = pkg.InstalledLocation;
try
{
var file = await installedLocationFolder.CreateFileAsync("ListCollection.json", Windows.Storage.CreationCollisionOption.GenerateUniqueName);
var filePath = file.Path;
DataContractJsonSerializer serialize = new DataContractJsonSerializer(typeof(ObservableCollection<String>));
using (Stream stream = await file.OpenStreamForWriteAsync())
{
serialize.WriteObject(stream, list);
stream.Flush();
}
}
catch (Exception ex)
{
var msg = ex.Message;
}
}
What this basically does is:
Find the file
Delete the file
Create a new file
Write your JSON to the file
I am really not an expert on this matter and it even to me seems pretty hacky but it apparently does the job.
If you can avoid writing to the install directory do it and use the method Frank J proposed

Mediaelement in Windows 8 Metro App

I have a scenario specific to my app. I am managing music file playlist in XML for my metro app. And its saving music files actual path like this
D:\MyMedia\1.mp3
I have media element in my XAML page and I am setting its Source like this.
mediaElement.Source = new Uri(#"D:\MyMedia\1.mp3", UriKind.Absolute);
mediaElement.Play();
but its not playing the media and its giving the error like this
MF_MEDIA_ENGINE_ERR_SRC_NOT_SUPPORTED : HRESULT - 0x80070005
So someone tell me how I can play some media file in MediaElement of metro app with absoulte path. Or how I can get stream of my local file to play this media in my mediaElement of Metro app.
To open files on the local system, you can use the FileOpenPicker to get the file and SetSource to set the media source.
var openPicker = new Windows.Storage.Pickers.FileOpenPicker();
openPicker.FileTypeFilter.Add(".mp3");
var file = await openPicker.PickSingleFileAsync();
var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
if (null != file)
{
mediaElement.SetSource(stream, file.ContentType);
mediaElement.Play();
}
There is only a limited number of locations on a user's PC that you can access. "D:\Mymedia" is not one of those. You will find all the necessary information in the Microsoft help. Check out these two articles:
Quickstart: Accessing files programmatically
File access and permissions in Windows Store apps
This can be done without a file picker. You just have to add Music Library capabilities to your app manifest, make sure the music is in My Music or on an SD Card, and use KnownFolders.MusicLibrary.
In short and in keeping with the music theme of the question:
"You might think file picker...
...but all I need is StorageFile"
//
// Opens and plays song titled "[Cars]You_Might_Think.mp3"
// in the 80s folder.
//
// IMPORTANT: the example song must be in the user's Music
// folder or SD card to be found. Also, the app manifest
// must have 'Music Library' capabilities enabled.
//
//
//
async void OpenAndPlayAwesomeSongFromThe80s()
{
Windows.Storage.StorageFolder folder = KnownFolders.MusicLibrary;
StorageFile song = await folder.GetFileAsync("80s\\[Cars]You_Might_Think.mp3");
if (song != null)
{
IRandomAccessStream stream = await song.OpenAsync(Windows.Storage.FileAccessMode.Read);
if (stream != null)
{
mediaElement = new MediaElement();
mediaElement.SetSource(stream, song.ContentType);
mediaElement.Play();
}
}
}
I know it's an old problem, I found a really simple solution..
Windows.Storage.StorageFile file = null;
mediaElement player = new MediaElement();
async Task PlayAsync()
{
if (file == null)
{
file = await OpenFileAsync();
try { player.MediaOpened -= Player_MediaOpenedAsync; } catch { }
try { player.MediaEnded -= Player_MediaEnded; } catch { }
try { player.MediaFailed -= Player_MediaFailed; } catch { }
player.MediaOpened += Player_MediaOpenedAsync;
player.MediaEnded += Player_MediaEnded;
player.MediaFailed += Player_MediaFailed;
player.SetPlaybackSource(MediaSource.CreateFromStorageFile(file)); //Works with media playback..
//player.Source = new Uri(mediasource, UriKind.RelativeOrAbsolute); //Doesn't work with media playback for some reason..
Playing = true;
Paused = false;
}
else
{
if (Paused)
{
player.Play();
Paused = false;
}
else
{
player.Pause();
Paused = true;
}
}
}
async Task<StorageFile> OpenFileAsync()
{
try
{
var ofd = new FileOpenPicker();
ofd.FileTypeFilter.Add("*");
return await ofd.PickSingleFileAsync();
}
catch { }
return null;
}

Categories

Resources