Answered by:
Setting msAudioCategory freezes the system

Question
-
Hello guys,
I've built a really simple app which reproduces all the mp3 files it finds in a folder picked by the user. The app implements the play to contract and I've decided it should also be able to play when it's the background, so I've decided to set the msAudioCategory attribute to the backgroundcapablemedia value.
Unfortunately, when the user picks a folder and runs the code for loading the first music, the system gets to a halt state and I can't do anything else (need to hit the pysical reboot button). Here's the code I'm using in my app. Am I doing anything wrong? thanks.
HTML file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>leitormp3</title>
<!-- WinJS references -->
<link href="//Microsoft.WinJS.0.6/css/ui-ligth.css" rel="stylesheet">
<script src="//Microsoft.WinJS.0.6/js/base.js"></script>
<script src="//Microsoft.WinJS.0.6/js/ui.js"></script>
<!-- leitormp3 references -->
<link href="/css/default.css" rel="stylesheet">
<script src="/js/default.js"></script>
</head>
<body>
<h1>Reprodução de ficheiros MP3</h1>
<div id="contentor">
<audio id="audio" controls></audio>
<div id="info"></div>
<button>Abrir pasta</button>
</div>
</body>
</html>
JavaScript File:
// For an introduction to the Blank template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232509
(function () {
"use strict";
var app = WinJS.Application;
var audio = null, musicas = null, posAtual = -1, info = null;
var playtoManager = null;
app.onactivated = function (eventObject) {
playtoManager = Windows.Media.PlayTo.PlayToManager.getForCurrentView();
playtoManager.addEventListener("sourcerequested", tipoConteudoReproduzido)
info = document.getElementById("info");
audio = document.getElementById("audio");
audio.setAttribute("msAudioCategory", "backgroundcapablemedia");
audio.addEventListener("mediafocuslost", perdeuFoco);
audio.addEventListener("mediafocusreceived", ganhouFoco);
audio.addEventListener("ended", iniciaMusica);
document.getElementById("contentor").appendChild(audio);
WinJS.Utilities.query("button")
.listen("click", abreMp3);
};
function perdeuFoco() {
audio.pause();
}
function ganhouFoco() {
audio.play();
}
function tipoConteudoReproduzido(e) {
var pedido = e.sourceRequest;
pedido.setSource(audio.msPlayToSource);
}
var Pickers = Windows.Storage.Pickers
function abreMp3() {
var picker = new Pickers.FolderPicker();
picker.fileTypeFilter.replaceAll([".mp3"]);
picker.suggestedStartLocation = Pickers.PickerLocationId.musicLibrary;
picker.pickSingleFolderAsync()
.done(function (item) {
carregaMusicas(item);
});
}
function carregaMusicas(pasta) {
if (!pasta) return;
var ordem = Windows.Storage.Search.CommonFileQuery.orderByName;
var tipos = [".mp3"];
var opcoes = new Windows.Storage.Search.QueryOptions(ordem, tipos);
pasta.createFileQueryWithOptions(opcoes)
.getFilesAsync().then(function (mp3s) {
musicas = mp3s;
posAtual = -1;
iniciaMusica();
});
}
function iniciaMusica(){
if( !musicas ) return;
posAtual = posAtual + 1;
if(posAtual > musicas.length ){
posAtual = 0;
}
var musica = musicas[posAtual];
musica.properties.getMusicPropertiesAsync()
.then( function(props){
info.innerHTML = props.trackNumber + "-" +
props.title +" (" +
new Date(props.duration).toLocaleTimeString() +
")";
audio.src = URL.createObjectURL(musica);
audio.play();
});
}
app.oncheckpoint = function (eventObject) {
// TODO: This application is about to be suspended. Save any state
// that needs to persist across suspensions here. You might use the
// WinJS.Application.sessionState object, which is automatically
// saved and restored across suspension. If you need to complete an
// asynchronous operation before your application is suspended, call
// eventObject.setPromise().
};
app.start();
})();
manifest:
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
<Identity Name="24ccc3aa-719c-4878-8292-32fb8d7cb7d0" Version="1.0.0.0" Publisher="CN=luisabreu" />
<Properties>
<DisplayName>leitormp3</DisplayName>
<Description>leitormp3</Description>
<PublisherDisplayName>luisabreu</PublisherDisplayName>
<Logo>images\storelogo.png</Logo>
</Properties>
<Prerequisites>
<OSMinVersion>6.2</OSMinVersion>
<OSMaxVersionTested>6.2</OSMaxVersionTested>
</Prerequisites>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="App" StartPage="default.html">
<VisualElements DisplayName="leitormp3" Logo="images\logo.png" SmallLogo="images\smalllogo.png" Description="leitormp3" ForegroundText="light" BackgroundColor="#000000">
<DefaultTile ShowName="allLogos" />
<SplashScreen Image="images\splashscreen.png" />
</VisualElements>
<Extensions>
<Extension Category="windows.backgroundTasks" StartPage="default.html">
<BackgroundTasks>
<Task Type="audio" />
</BackgroundTasks>
</Extension>
</Extensions>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
</Capabilities>
</Package>Luis Abreu
Sunday, May 13, 2012 8:21 PM
Answers
-
Yes your app must register for media transport controls when they are going to play in the background and you should implement them as follows:http://msdn.microsoft.com/en-us/library/windows/apps/hh452722.aspx
Jeff Sanders (MSFT)
- Proposed as answer by Jeff SandersMicrosoft employee, Moderator Monday, May 14, 2012 3:48 PM
- Marked as answer by Jeff SandersMicrosoft employee, Moderator Tuesday, May 15, 2012 12:09 PM
Monday, May 14, 2012 3:48 PMModerator
All replies
-
Found the problem: it seems like you need to handle the playpressed, stoppressed and pausepressed events from MediaControl.
Luis Abreu
- Marked as answer by Luis Miguel Abreu Sunday, May 13, 2012 8:53 PM
- Unmarked as answer by Luis Miguel Abreu Sunday, May 13, 2012 9:36 PM
Sunday, May 13, 2012 8:53 PM -
Btw, why do I need to handle these events? I mean, I've just set them up and added no code to them. I was under the impression that those events would only be useful when you needed to interact with those special keys which allows you to start/stop music without going to the app.
can someone give more info about this topic?
thanks.
Luis Abreu
Sunday, May 13, 2012 9:38 PM -
And just some more info on this. It seems like freezing will happen whenever you miss one of the necessary steps. For instance, I've had the same problem in a different pc when I forgot to add the background audio task to the manifest of the app...
Luis Abreu
Monday, May 14, 2012 10:40 AM -
So everything is OK when you use the correct syntax and manifest?
Jeff Sanders (MSFT)
Monday, May 14, 2012 3:34 PMModerator -
Yes your app must register for media transport controls when they are going to play in the background and you should implement them as follows:http://msdn.microsoft.com/en-us/library/windows/apps/hh452722.aspx
Jeff Sanders (MSFT)
- Proposed as answer by Jeff SandersMicrosoft employee, Moderator Monday, May 14, 2012 3:48 PM
- Marked as answer by Jeff SandersMicrosoft employee, Moderator Tuesday, May 15, 2012 12:09 PM
Monday, May 14, 2012 3:48 PMModerator -
Hello Jeff.
Yes, it does play.
I understand that failing one of the steps is enough for it not to work. However, can't really understand how missing an event which is only fired for hw buttons should freeze my system and force me to reboot it through the hw button...
I'm going to read the white paper you've mentioned before complaining about the mediacontrol events requirement :)
thanks again
Luis Abreu
Monday, May 14, 2012 9:23 PM -
Hey Luis,
Yes I agree it is bad (and I will try a repro and file a bug if it does repro) but you do have to play by the rules too :-)
-Jeff
Jeff Sanders (MSFT)
Tuesday, May 15, 2012 12:09 PMModerator -
yes, I know that.
but it would really help if the quickstarts did mention it, right? ;)
in order to reproduce it, open the sample which shows the background behavior, and, for instance, comment the mediacontrol events. I've managed to reproduce it on my 2 machines by doing that.
Luis Abreu
Tuesday, May 15, 2012 8:59 PM