I'm trying to update the album art for a background playing track in Windows 8.1 Store app (C#/Xaml) but although I get no exceptions, the image doesn't update in the little transport popup...
this is the code I'm executing to update it:
var track = App.MediaPlayer.Tag as Track;
await App.Api.Cache.DownloadFile("currentalbumart.png", new Uri(track.medium_image_url));
// Get the updater.
SystemMediaTransportControlsDisplayUpdater updater = App.SystemControls.DisplayUpdater;
updater.Type = MediaPlaybackType.Music;
updater.MusicProperties.AlbumArtist = track.artist;
updater.MusicProperties.Title = track.name;
updater.Thumbnail = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appdata:///local/currentalbumart.png"));
updater.Update();
The DownloadFile method executes without any issue, and if I navigate to the local folder, indeed the image does get downloaded. I thought perhaps I'm using the wrong URI to it, but I don't get any exceptions when I assign it to the thumbnail...
what might be wrong here? many thanks
I actually had this problem for ages but finally fixed it today, after about 20+hours on previous apps to get it working. If you use the following code to update your thumbnail, you can use a html link:
updater.thumbnail = Windows.Storage.Streams.RandomAccessStreamReference.createFromUri(new Windows.Foundation.Uri("http://www.example.com/logo.jpg"));
This leaves the full code for the function to be:
//Used to update the media controls etc
function UpdateSongInfoManually(artist,songName,AlbumArtist, SongArt) {
// Get the updater.
var updater = systemMediaControls.displayUpdater;
updater.type = 1; //1=Music
// Music metadata.
updater.musicProperties.AlbumArtist = artist;
updater.musicProperties.AlbumArtist = mixName;
updater.musicProperties.Title = songTitle;
updater.thumbnail = Windows.Storage.Streams.RandomAccessStreamReference.createFromUri(new Windows.Foundation.Uri(MixArt));
// Set the album art thumbnail.
// RandomAccessStreamReference is defined in Windows.Storage.Streams
//updater.Thumbnail =
// RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Music/music1_AlbumArt.jpg"));
// Update the system media transport controls.
updater.update();
}
I have a similar problem in a Windows 8.1 Phone (Store) app. First I tried to copy MP3 files (with ID3 tags) and a folder.jpg file as album art using Windows Explorer to the Phones Music library (Music//). Using standard Music app everything works fine.
Than I tried to do the same inside the app I am developing. I download mp3 and jpg file from a server and stored them into the music library. I verified the result with the phones standard Music App. The ID3 tags are detected correctly but the album art jpg file is not shown. And now the thing becomes completely magic. Using Explorer I copied the jpg file to the PC and checked it. Jpg looks fine. Than I copied it back to the phone. And now standard music app shows correct album art !!
Maybe it has something to do with file security.
Related
I'm trying to help out a client with an Adobe AIR application that suddenly stopped working on Mac OS Sierra. I haven't developed the app myself, so I am trying to do my best to solve the problem. It's essentially a Flex application written in Actionscript 3. When I was debugging I can see that I am getting the following error:
[ERROR] Error #2032: Stream Error.
The way the application works is that it first makes a web request to the server and gets an XML with a number of songs. No problem there.
After that the application downloads the first song in the XML result and starts playing.
When the first song starts playing the application then downloads the second song in the XML-list, when that download is finished it starts downloading the next one and so forth. The files being downloaded seems to be rather large, a couple of MB's.
So the first download works just fine, but all the other track downloads fails with Stream Error #2032. It seems I dont get any response headers from the failed requests, only the first one. I have a crossdomain.xml on the server.
This app works just fine on Mac OS X El Capitan and Windows, but with Sierra I am getting this error. The code is not that complex, it makes an API URL Request with an URLLoader and saves the file to disk. I have also tried using URLStream instead, same issue.
This is some of the code for example:
public function downloadTrack(track:Object, storeName:String, apiKey:String):void {
this.setCurrentTrack(track);
this.urlParameters.storeName = storeName;
this.urlParameters.keystring = apiKey;
this.urlLoader = new URLLoader();
this.urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
this.urlRequest = new URLRequest("/api/" + 'download/' +
this.currentTrack.id + "?time=" + new Date().getTime());
this.urlRequest.method = URLRequestMethod.POST;
this.urlRequest.data = this.urlParameters;
this.addEventListeners();
this.urlLoader.load(this.urlRequest);
}
private function loaded(e:Event):void {
this.fileData = e.target.data;
writeFile();
}
private function writeFile():void {
var filePath:String = this.currentTrack.md5 + '.ogg';
var cacheFile:File = this.downloadDirectory.resolvePath('.' + filePath);
this.fileStream.addEventListener(Event.CLOSE, saveReady);
this.fileStream.openAsync(cacheFile, FileMode.WRITE);
this.fileStream.writeBytes(fileData,0,fileData.length);
this.fileStream.close();
}
In the addEventListeners()-method, event-listeners for the URLLoader is added, and it's the urlloader that fires the IOError.
A weird thing that has happened twice is that the app suddenly starts to work as normal and downloads all of the files successively. Then after a couple of minutes it starts acting up again and nothing works. I am really having a hard time to understand where the error lies. I am no Adobe AIR/Flex-expert, so maybe you can point me in the right direction? I am pretty close to giving up on this one.
Thanks!
Try to change the destination, probably you don't have permissions to
write there.
Use the latest AIR SDK
Would be much better if you will share the project where it reproduced so I could check on my machine
I have set up a Windows Phone project along with its associated BackgroundTask project, and have also done the needed declarations as explained in this article.
I need to select an audio file from the app UI (from the Music Library), and assign it to the BackgroundMediaPlayer to play it, so that the song can be played when the UI is in foreground, and also when it is suspended or the screen is locked.
I have tried the following but it does not work:
Set file path from UI:
StorageFile file = (await KnownFolders.MusicLibrary.GetFileAsync(
"Song from Music Library.mp3"));
BackgroundMediaPlayer.Current.SetUriSource(new System.Uri(file.Path,
UriKind.RelativeOrAbsolute));
BackgroundMediaPlayer.Current.Play();
Result: No audio is played. No exceptions are thrown.
Pass the file path as string to the backgroundtask, search for the file from Music Library and play it:
IReadOnlyList<StorageFile> songs = await
KnownFolders.MusicLibrary.GetFilesAsync(CommonFileQuery.OrderByName);
StorageFile fileToPlay = songs.AsQueryable().Single(
s => s.Path == toPlay);
BackgroundMediaPlayer.Current.SetFileSource(fileToPlay);
Result: The debugger does not move forward after "StorageFile fileToPlay = songs.AsQueryable().Single(s => s.Path == toPlay);". It just stops there.
Again, no audio is played. No exceptions are thrown.
Appreciate your help.
BackgroundMediaPlayer set Uri source of Media library item
StorageFile file = (await KnownFolders.MusicLibrary.GetFilesAsync()).FirstOrDefault();
BackgroundMediaPlayer.Current.SetUriSource(new Uri(file.Path, UriKind.RelativeOrAbsolute));
See the answer.
I was trying to recreate the simle Text to Speech example used on the MSDN website. However whenever the code came to create the instance of the SpeechSynthesizer class it failed with a Unauthorised Acception error when running on the WP8.1 emulator. I currently do not have an actual device to test on to see if this makes a difference.
My code was simply:
private async void TTS()
{
// The media object for controlling and playing audio.
MediaElement mediaElement = new MediaElement();
// The object for controlling the speech synthesis engine (voice).
var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();
// Generate the audio stream from plain text.
SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync("Hello World");
// Send the stream to the media object.
mediaElement.SetSource(stream, stream.ContentType);
mediaElement.Play();
}
I know there was an issue with the SpeechSynthesizer in Windows 8.1, and I found solutions to this when looking to fix the problem, but found little about the problem with WP8.1 SpeechSynthesizer. Has anybody else came across this problem and found a fix?
You should add one DeviceCapability in Package.appxmanifest file:
In DeviceCapability Tab, check the microphone, because it will provides access to the microphone’s audio feed, which allows the app to record audio from connected microphones.
Look at this library: App capability declarations (Windows Runtime apps)
I'm trying to get sound working on my iPhone game using the Web Audio API. The problem is that this app is entirely client side. I want to store my mp3s in a local folder (and without being user input driven) so I can't use XMLHttpRequest to read the data. I was looking into using FileSystem but Safari doesn't support it.
Is there any alternative?
Edit: Thanks for the below responses. Unfortunately the Audio API is horribly slow for games. I had this working and the latency just makes the user experience unacceptable. To clarify, what I need is sounething like -
var request = new XMLHttpRequest();
request.open('GET', 'file:///./../sounds/beep-1.mp3', true);
request.responseType = 'arraybuffer';
request.onload = function() {
context.decodeAudioData(request.response, function(buffer) {
dogBarkingBuffer = buffer;
}, onError);
}
request.send();
But this gives me the errors -
XMLHttpRequest cannot load file:///sounds/beep-1.mp3. Cross origin requests are only supported for HTTP.
Uncaught Error: NETWORK_ERR: XMLHttpRequest Exception 101
I understand the security risks with reading local files but surely within your own domain should be ok?
I had the same problem and I found this very simple solution.
audio_file.onchange = function(){
var files = this.files;
var file = URL.createObjectURL(files[0]);
audio_player.src = file;
audio_player.play();
};
<input id="audio_file" type="file" accept="audio/*" />
<audio id="audio_player" />
You can test here:
http://jsfiddle.net/Tv8Cm/
Ok, it's taken me two days of prototyping different solutions and I've finally figured out how I can do this without storing my resources on a server. There's a few blogs that detail this but I couldn't find the full solution in one place so I'm adding it here. This may be considered a bit hacky by seasoned programmers but it's the only way I can see this working, so if anyone has a more elegent solution I'd love to hear it.
The solution was to store my sound files as a Base64 encoded string. The sound files are relatively small (less than 30kb) so I'm hoping performance won't be too much of an issue. Note that I put 'xxx' in front of some of the hyperlinks as my n00b status means I can't post more than two links.
Step 1: create Base 64 sound font
First I need to convert my mp3 to a Base64 encoded string and store it as JSON. I found a website that does this conversion for me here - xxxhttp://www.mobilefish.com/services/base64/base64.php
You may need to remove return characters using a text editor but for anyone that needs an example I found some piano tones here - xxxhttps://raw.github.com/mudcube/MIDI.js/master/soundfont/acoustic_grand_piano-mp3.js
Note that in order to work with my example you're need to remove the header part data:audio/mpeg;base64,
Step 2: decode sound font to ArrayBuffer
You could implement this yourself but I found an API that does this perfectly (why re-invent the wheel, right?) - https://github.com/danguer/blog-examples/blob/master/js/base64-binary.js
Resource taken from - here
Step 3: Adding the rest of the code
Fairly straightforward
var cNote = acoustic_grand_piano.C2;
var byteArray = Base64Binary.decodeArrayBuffer(cNote);
var context = new webkitAudioContext();
context.decodeAudioData(byteArray, function(buffer) {
var source = context.createBufferSource(); // creates a sound source
source.buffer = buffer;
source.connect(context.destination); // connect the source to the context's destination (the speakers)
source.noteOn(0);
}, function(err) { console.log("err(decodeAudioData): "+err); });
And that's it! I have this working through my desktop version of Chrome and also running on mobile Safari (iOS 6 only of course as Web Audio is not supported in older versions). It takes a couple of seconds to load on mobile Safari (Vs less than 1 second on desktop Chrome) but this might be due to the fact that it spends time downloading the sound fonts. It might also be the fact that iOS prevents any sound playing until a user interaction event has occured. I need to do more work looking at how it performs.
Hope this saves someone else the grief I went through.
Because ios apps are sandboxed, the web view (basically safari wrapped in phonegap) allows you to store your mp3 file locally. I.e, there is no "cross domain" security issue.
This is as of ios6 as previous ios versions didn't support web audio api
Use HTML5 Audio tag for playing audio file in browser.
Ajax request works with http protocol so when you try to get audio file using file://, browser mark this request as cross domain request. Set following code in request header -
header('Access-Control-Allow-Origin: *');
I'm having trouble with posting an image from my canvas application to the user's albums. According to the Facebook docs:
In order to publish a photo to a user’s album, you must have the publish_stream permission. With that granted, you can upload a photo by issuing an HTTP POST request with the photo content and an optional description to one these to Graph API connections:
https://graph.facebook.com/USER_ID/photos - The photo will be published to an album created for your app. We automatically create an album for your app if it does not already exist. All photos uploaded this way will then be added to this same album.
https://graph.facebook.com/ALBUM_ID/photos - The photo will be published to a specific, existing photo album, represented by the ALBUM_ID.
So, going by point one, if I upload an image like this...
Facebook.api("me/photos",imagePostCallback,{message:"",image:myImageBitmap,fileName:''},URLRequestMethod.POST);
...then I can expect it to place my image in an album named for my app, which it will create if necessary?
Not so.
What actually happens when the album doesn't exist is that the uploaded image is pushed into any other handy albums that exist, which are usually for (and created by) other applications. This is a bit of a pain.
So far I've tried the following:
Disabling sandbox mode. I had thought that the app might be unable to create new albums because it was in sandbox mode, however disabling sandbox mode made no difference and I can create albums directly with it enabled.
Checking for the existence of my album and creating it if necessary. I can check for my album and create it if it does not exist, but I cannot then upload an image because the POST call to Facebook.api to upload the image will fail if it is not called as a direct result of a user interaction.
And so now I'm a bit stumped. Obviously I can't have the possibility of my app posting images to a competitors album, but at the moment the only alternative I can see will involve effectively making the user submit their image twice if an album has to be created. Any ideas?
I'm guessing you need the access_token in your params :) When posting something on a user's facebook, you always need this one (not always necessary when getting information). The way to get the accesstoken is shown below :)
public function post():void
{
var _params:Object = new Object();
_params.access_token = Facebook.getSession().accessToken;
_params.message = "";
_params.image = myImageBitmap;
_params.fileName = "";
Facebook.api("me/photos", imagePostCallback, _params, URLRequestMethod.POST);
}
also make sure that you have the right permissions when asking for permissions with your app.
EDIT
Ok, so I've missed your edit a bit there ;) it should be possible to create your own album. Take a look at this php-code for graph api. The code should also be able to be parsed to AS3.
http://developers.facebook.com/blog/post/498/
EDIT2
ok, i've done some more digging (seemed interesting to know). This should actually work when using graph api.
FB.api('/me/albums', albumCreateCallback, {name: 'name of the album', message: 'description of the album'}, URLRequestMethod.POST);
When you then call for another api call to upload your image in the albumCreateCallback, it should work and upload your image (according to what i've found).