我的问题:
我使用Cordova的Media Class。 MP3文件只播放一次(第一次)。
代码:
将此代码添加到Cordova Starter项目中以重现我的问题:
var playCounter = 0;
function playMP3(){
console.log("playMP3() counter " + playCounter);
var my_media = new Media("app/www/test.mp3");//ressource buildAction == content
my_media.play();
playCounter++;
}
[...]
<p onclick="playMP3();">Click to Play MP3</p>
VS输出:
[...]
GapBrowser_Navigated :: /app/www/index.html
'UI Task' (Managed): Loaded 'System.ServiceModel.Web.dll'
'UI Task' (Managed): Loaded 'System.ServiceModel.dll'
Log:"onDeviceReady. You should see this message in Visual Studio's output window."
'UI Task' (Managed): Loaded 'Microsoft.Xna.Framework.dll'
Log:"playMP3() counter 0"
'UI Task' (Managed): Loaded 'System.SR.dll'
Log:"media on status :: {\"id\": \"fa123123-bc55-a266-f447-8881bd32e2aa\", \"msg\": 1, \"value\": 1}"
A first chance exception of type 'System.ArgumentException' occurred in mscorlib.dll
Log:"media on status :: {\"id\": \"fa123123-bc55-a266-f447-8881bd32e2aa\", \"msg\": 1, \"value\": 2}"
Log:"media on status :: {\"id\": \"fa123123-bc55-a266-f447-8881bd32e2aa\", \"msg\": 2, \"value\": 2.141}"
Log:"media on status :: {\"id\": \"fa123123-bc55-a266-f447-8881bd32e2aa\", \"msg\": 1, \"value\": 4}"
Log:"playMP3() counter 1"
A first chance exception of type 'System.ArgumentException' occurred in mscorlib.dll
A first chance exception of type 'System.IO.IOException' occurred in mscorlib.dll
A first chance exception of type 'System.IO.IsolatedStorage.IsolatedStorageException' occurred in mscorlib.dll
Log:"media on status :: {\"id\": \"2de3388c-bbb6-d896-9e27-660f1402bc2a\", \"msg\": 9, \"value\": 5}"
我的配置:
WorkAround(种类):
任何帮助都是受欢迎的,因为我可能会在几天内被阻止,而且我在任何地方都找不到有用的信息。
另外,你能告诉我这个代码是否适用于你的配置?
更新:添加演示代码,Cordova 1.8.0rc1
使用全局变量。让实例保持活力。
结果
代码
function onDeviceReady()
{
document.getElementById("welcomeMsg").innerHTML += "Cordova is ready! version=" + window.device.cordova;
console.log("onDeviceReady. You should see this message in Visual Studio's output window.");
my_media = new Media("app/www/test.mp3");//ressource buildAction == content
my_media2 = new Media("app/www/test2.mp3");//ressource buildAction == content
}
var playCounter = 0;
var my_media = null;
function playMP3(){
console.log("playMP3() counter " + playCounter);
my_media.play();
playCounter++;
}
var my_media2 = null;
function playMP32(){
console.log("playMP32() counter " + playCounter);
my_media2.play();
playCounter++;
}
</script>
[...]
<p onclick="playMP3();">Click to Play MP3</p>
<p onclick="playMP32();">Click to Play MP3 2</p>
VS输出:
Log:"onDeviceReady. You should see this message in Visual Studio's output window."
INFO: startPlayingAudio could not find mediaPlayer for 71888b14-86fe-4769-95c9-a9bb05d5555b
Log:"playMP32() counter 0"
INFO: startPlayingAudio could not find mediaPlayer for 71888b14-86fe-4769-95c9-a9bb05d5555b
Log:"playMP32() counter 1"
Log:"playMP3() counter 2"
INFO: startPlayingAudio could not find mediaPlayer for b60fa266-d105-a295-a5be-fa2c6b824bc1
A first chance exception of type 'System.ArgumentException' occurred in System.Windows.dll
Error: El parámetro es incorrecto.
Log:"playMP32() counter 3"
INFO: startPlayingAudio could not find mediaPlayer for 71888b14-86fe-4769-95c9-a9bb05d5555b
更新:Cordova 2.0.0
我用2.0.0的测试用例提升了Apache错误报告。
有人可以复制吗?
答案 0 :(得分:2)
我看到你在第二次点击时收到了IsolatedStorageException,这让我觉得该文件被第一个Media
实例保持打开状态,这阻止了它再次被访问。
我建议您确保每个文件只创建一个Media
实例,或者查看是否有办法首先处理旧实例。
这是我想尝试的(但我没有测试过):
var playCounter = 0;
// moved my_media here so it won't be recreated
var my_media = new Media("app/www/test.mp3");//ressource buildAction == content
function playMP3(){
console.log("playMP3() counter " + playCounter);
my_media.play();
playCounter++;
}
[...]
<p onclick="playMP3();">Click to Play MP3</p>
答案 1 :(得分:1)
差点忘了......这适用于我的目的。希望它有所帮助; - )
WP7.5 / Cordova 1.9.0
要求:据我所知,仅适用于.wav文件。我不得不转换我的.mp3文件,因为它们会抛出丑陋的异常。
插件:C#:
namespace Cordova.Extension.Commands
{
public class PGSoundFX : BaseCommand
{
public Dictionary <string, SoundEffect> fxSoundMap = new Dictionary<string,SoundEffect>();
public enum FXType
{
Load=0,
Play=1
}
[DataContract]
public class FXOption
{
[DataMember]
public string audioSrc;
[DataMember]
public string audioRef;
[DataMember]
public FXType fxType;
}
public void groAudio(string options)
{
FrameworkDispatcher.Update();
FXOption opts;
opts = WP7CordovaClassLib.Cordova.JSON.JsonHelper.Deserialize<FXOption>(options);
if (opts != null)
{
try
{
switch (opts.fxType)
{
case FXType.Load:
loadSound(opts.audioSrc, opts.audioRef);
break;
case FXType.Play:
Dictionary<string, SoundEffect>.KeyCollection keyCol = fxSoundMap.Keys;
foreach (string tmp in keyCol)
{
if ((opts.audioRef).Equals(tmp))
playSound(fxSoundMap[tmp]);
}
break;
}
}
catch
{
Debug.WriteLine("PGSoundFX: loadSound Error ... null parameter(s).");
}
}
}
/// <summary>
/// Loads a wav file into an XNA Framework SoundEffect.
/// </summary>
/// <param name="Sound">The SoundEffect to play.</param>
private void playSound(SoundEffect Sound)
{
Sound.Play();
DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
}
/// <summary>
/// Loads a wav file into an XNA Framework SoundEffect.
/// </summary>
/// <param name="SoundFilePath">Relative path to the wav file.</param>
/// <param name="Sound">The SoundEffect to load the audio into.</param>
private void loadSound(String SoundFilePath, String SoundName)
{
if (fxSoundMap.Keys != null)
{
Dictionary<string, SoundEffect>.KeyCollection keyColl = fxSoundMap.Keys;
foreach (string tmp in keyColl)
{
if (SoundName.Equals(tmp))
return;
}
}
SoundEffect Sound = null;
try
{
// Holds informations about a file stream.
StreamResourceInfo SoundFileInfo = Application.GetResourceStream(new Uri(SoundFilePath, UriKind.Relative));
// Create the SoundEffect from the Stream
Sound = SoundEffect.FromStream(SoundFileInfo.Stream);
fxSoundMap[SoundName] = Sound;
DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
}
catch (NullReferenceException)
{
Debug.WriteLine("Couldn't load sound " + SoundFilePath);
}
}
}
}
使用Javascript:插件:
PhoneGap.addConstructor(function() {
navigator.plugins.pgSoundFX =
{
playSound:function(fxName)
{
var options = {"audioRef":fxName,"fxType":1};
PhoneGap.exec(null, null, "PGSoundFX", "groAudio", options);
},
loadSound:function(fxSrc, fxName)
{
var options = {"audioSrc":fxSrc,"audioRef":fxName,"fxType":0};
PhoneGap.exec(null, null, "PGSoundFX", "groAudio", options);
}
}
});
使用Javascript:使用:
//NOTE: Allows you to pre-load sound effect files
//initialize pgSoundFX plugin
if (!navigator.plugins) {
console.log("plugIns do not exist!");
navigator.plugins = {};
}
navigator.plugins.pgSoundFX.loadSound("www/audio/file1.wav", "item1");
navigator.plugins.pgSoundFX.loadSound("www/audio/file2.wav", "item2");
navigator.plugins.pgSoundFX.loadSound("www/audio/file3.wav", "item3");
:
:
//NOTE: Play whenever needed
navigator.plugins.pgSoundFX.playSound("item1");
当然,您的文件位置(www / audio /),名称(file1等)和引用名称(item1等)都是您想要的。和大多数人一样,有很多方法可以改进这些代码......随意。我的用例预装了五个.wav文件,大小从28k到364k不等,并在用户游戏过程中播放。
答案 2 :(得分:0)
我不确定这是正确的答案,因为我没有尝试,但认为这是一个头脑风暴。
首先使用var my_media = new Media(src, onSuccess, onError);
ctor创建您的音频,并且成功播放它并在出现错误时首先尝试使用media.release
代码发布它。
如果你知道其他一些事件或行动要发布它会更合适。
编辑:我刚注意到它,你没有使用stop
媒体,你也可以尝试在需要时使用它,例如playMP3()
的开头如果媒体不为空尝试停止它首先。
干杯。
答案 3 :(得分:0)
我认为问题可能在于Silverlight每页仅允许一个媒体实例的限制......并且由于PG / Cordova本质上是单页webBrowser实例,因此它只能有一个媒体实例。我正在玩构建XNA SoundEffect插件来解决这个问题。
答案 4 :(得分:0)
是一个Cordova错误 https://issues.apache.org/jira/browse/CB-941
在他的gitHub回购中通过purpulecabbage解决了。看到关于错误报告的评论。