我的问题:
我使用科尔多瓦的媒体类。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}"
我的配置:
- 科尔多瓦-1.6.1.js
- 卢米亚 800
- WP 7.5 (7.10.7740.16)
解决方法(有点):
- 停用应用程序(关闭屏幕)
- 重新激活应用程序(打开屏幕)
- ->你再拍一次。
欢迎任何帮助,因为我自五月天以来就被阻止了,而且我在任何地方都没有找到有用的信息。
另外,你能告诉我这段代码是否适用于你的配置吗?
.
.
.
更新:添加一个演示代码,科尔多瓦 1.8.0rc1
使用全局变量保持实例活动状态。
结果
- test2.mp3 已播放,可以正常重播。
- 测试.mp3根本没有播放。
- 这是您播放的第一个可以工作的文件。
法典
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
.
.
.
更新:科尔多瓦 2.0.0
我用 2.0.0 的测试用例更新了 Apache 错误报告。
任何人都可以重现这个吗?
错误报告链接:https://issues.apache.org/jira/browse/CB-941
我看到您在第二次单击时得到一个隔离存储异常,这让我认为该文件被第一个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>
差点忘了...这适用于我的目的。希望它有帮助;-)
WP7.5/科尔多瓦 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:Plugin:
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:Use:
//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等)是您想要的。与大多数一样,有很多方法可以改进此代码...随意。我的用例预加载了五个大小从 28k 到 364k 不等的.wav文件,并在整个用户游戏过程中播放它们。
我不确定这是正确的答案,因为我没有尝试过,但将其视为头脑风暴。
首先使用 var my_media = new Media(src, onSuccess, onError);
ctor 创建音频,成功后只需播放它,出错时首先尝试使用media.release
代码发布它。
好吧,如果您知道要发布的其他事件或操作,那将更合适。
编辑:我刚刚注意到,您没有将stop
用于媒体,您也可以在需要时尝试使用它,例如playMP3()
的开头,如果媒体不为空,请尝试先停止它。
干杯。
问题可能在于 Silverlight 每页只允许一个媒体实例的限制......由于PG/Cordova本质上是一个单页WebBrowser实例,因此它只能有一个媒体实例。我正在尝试构建一个XNA SoundEffect插件来解决这个问题。
是一个科尔多瓦错误https://issues.apache.org/jira/browse/CB-941
由 purpulecabbage 在他的 gitHub 存储库中解决。 请参阅对错误报告的评论。