我正在开发一款适用于 iOS 的 PhoneGap 应用程序,它可以让您收听 MP3 和观看 MP4。
通常,我只会使用<a href="file.mp3">file.mp3</a>
或<video src="file.mp3"></video>
播放文件并让系统媒体播放器处理事情。这一次,要求在屏幕关闭时继续播放音频。默认处理是在屏幕锁定时淡出并暂停媒体。PhoneGap API 文档提供了一些示例代码,其中包含playAudioWhenScreenIsLocked选项。该代码似乎可以正常工作,因为当屏幕锁定时 MP3 会继续播放。
我遇到的问题是所述文件开始播放需要相当长的时间。例如,一个 27MB 的 MP3 文件在 iPhone 4s (3g) 上开始播放需要 1 分 50 秒,而在 iPad 2 (WiFi) 上需要 2 分钟。在我的桌面上下载同一个文件需要几秒钟。似乎它必须在开始播放之前下载整个文件。这似乎没有必要。为了补充这个理论,如果我尝试播放 MP4(使用media.play()
),它需要更长的时间然后关闭应用程序。
config.xml(可识别部分替换为 xxx):
<?xml version="1.0" encoding="UTF-8"?>
<!-- config.xml reference: https://build.phonegap.com/docs/config-xml -->
<widget xmlns = "http://www.w3.org/ns/widgets" xmlns:gap = "http://phonegap.com/ns/1.0" id = "org.xxx.xxxbeta" version = "2.0">
<name>xxx Beta</name>
<description>xxx Live /// Design update</description>
<author href="http://www.xxx.org" email="xxx@xxx.org">xxx</author>
<!-- Enable individual API permissions by defining each here. The 'device' permission is required for the 'deviceready' event. -->
<feature name="http://api.phonegap.com/1.0/device" />
<!-- Customize your app and platform with the preference element. -->
<!-- If you do not want any permissions to be added to your app, add the following tag to your config.xml; you will still have the INTERNET permission on your app, which PhoneGap requires. -->
<preference name="permissions" value="none"/>
<preference name="phonegap-version" value="2.9.0" /> <!-- all: current version of PhoneGap -->
<preference name="orientation" value="default" /> <!-- all: default means both landscape and portrait are enabled -->
<preference name="target-device" value="universal" /> <!-- all: possible values handset, tablet, or universal -->
<preference name="fullscreen" value="false" /> <!-- all: hides the status bar at the top of the screen -->
<preference name="webviewbounce" value="true" /> <!-- ios: control whether the screen 'bounces' when scrolled beyond the top -->
<preference name="prerendered-icon" value="false" /> <!-- ios: if icon is prerendered, iOS will not apply it's gloss to the app's icon on the user's home screen -->
<preference name="stay-in-webview" value="false" /> <!-- ios: external links should open in the default browser, 'true' would use the webview the app lives in -->
<preference name="ios-statusbarstyle" value="black-opaque" /> <!-- ios: black-translucent will appear black because the PhoneGap webview doesn't go beneath the status bar -->
<preference name="detect-data-types" value="true" /> <!-- ios: controls whether data types (such as phone no. and dates) are automatically turned into links by the system -->
<preference name="exit-on-suspend" value="false" /> <!-- ios: if set to true, app will terminate when home button is pressed -->
<preference name="show-splash-screen-spinner" value="false" /> <!-- ios: if set to false, the spinner won't appear on the splash screen during app loading -->
<preference name="auto-hide-splash-screen" value="true" /> <!-- ios: if set to false, the splash screen must be hidden using a JavaScript API -->
<preference name="disable-cursor" value="false" /> <!-- blackberry: prevents a mouse-icon/cursor from being displayed on the app -->
<preference name="android-minSdkVersion" value="14" /> <!-- android: MIN SDK version supported on the target device. MAX version is blank by default. -->
<preference name="android-installLocation" value="auto" /> <!-- android: app install location. 'auto' will choose. 'internalOnly' is device memory. 'preferExternal' is SDCard. -->
<!-- Plugins can also be added here. A list of available plugins are available at https://build.phonegap.com/docs/plugins-->
<!--<gap:plugin name="GAPlugin" />-->
<!-- Define app icon for each platform. -->
<icon src="images/logo.png" />
<icon src="images/Icons/icon-57.png" gap:platform="ios" width="57" height="57" />
<icon src="images/Icons/icon-72.png" gap:platform="ios" width="72" height="72" />
<icon src="images/Icons/icon-114.png" gap:platform="ios" width="114" height="114" />
<icon src="images/Icons/icon-144.png" gap:platform="ios" width="144" height="144" />
<!-- Define app splash screen for each platform. -->
<gap:splash src="images/LaunchScreens/launch-iphone-app-P.png" gap:platform="ios" width="320" height="480" />
<gap:splash src="images/LaunchScreens/launch-iphone-app-P-2x.png" gap:platform="ios" width="640" height="960" />
<gap:splash src="images/LaunchScreens/launch-iphone-5-app-P.png" gap:platform="ios" width="640" height="1136" />
<gap:splash src="images/LaunchScreens/launch-ipad-app-P.png" gap:platform="ios" width="768" height="1024" />
<gap:splash src="images/LaunchScreens/launch-ipad-app-P-2x.png" gap:platform="ios" width="1536" height="2048" />
<gap:splash src="images/LaunchScreens/launch-ipad-app-L.png" gap:platform="ios" width="1024" height="768" />
<gap:splash src="images/LaunchScreens/launch-ipad-app-L-2x.png" gap:platform="ios" width="2048" height="1536" />
<!-- Define access to external domains. -->
<!--
<access /> - A blank access tag denies access to all external resources.
<access origin="*" /> - A wildcard access tag allows access to all external resource.
<access origin="http://127.0.0.1*"/> - allow local pages only
<access origin="http://phonegap.com" /> - allow any secure requests to http://phonegap.com/
<access origin="http://xxx.org" subdomains="true" /> - same as above, but including subdomains, such as http://build.phonegap.com/
<access origin="http://xxx.org" browserOnly="true" /> - only allows http://phonegap.com to be opened by the child browser.
-->
</widget>
HTML(可识别部分替换为 xxx):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Featured Series | xxx Live</title>
<!-- required for the redirectToSystemBrowser() function -->
<script src="phonegap.js"></script>
<!-- used to change the formats of dates -->
<script src="date.js"></script>
<!-- jquery (we might as well use it) -->
<script src="jquery-1.10.1.min.js"></script>
<!-- our javascripts -->
<script src="xxxlive.js"></script>
</head>
<body class="featuredseries">
<header>
<h1><a href="index.html"><abbr title="xxx">xxx</abbr> <span>Live</span></a></h1>
</header>
<section id="content">
</section>
<!-- page specific javascripts -->
<script>
// load the featured series content
seriesDownload(featuredseries);
</script>
</body>
</html>
JavaScript(可识别部分替换为 xxx):
// phonegap api media playing
function playAudio(url) {
// Play the audio file at url
var my_media = new Media(url,
// success callback
function () {
console.log("playAudio():Audio Success");
},
// error callback
function (err) {
console.log("playAudio():Audio Error: " + err);
}
);
// Play audio even if the screen is off
my_media.play({ playAudioWhenScreenIsLocked : true });
}
// generic get JSON data function
function fetchJSONFile(path, callback) {
var httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200) {
var data = JSON.parse(httpRequest.responseText);
if (callback) callback(data);
}
}
};
// false tells it to be synchronous instead of asynchronous
httpRequest.open('GET', path, false);
httpRequest.send();
}
// get a bunch of series information from a json api
function seriesDownload(seriestitle) {
var series, number, description;
// tell the function where the JSON data is
fetchJSONFile('http://www.xxx.org/api/seriesdownload/?series=' + seriestitle, function(data) {
// do something with your data
// alert(JSON.stringify(data));
// alert(data.title + ', ' + data.camelcase);
series = data.series;
number = data.seriesnumber;
description = data.description;
$('#content').append('<h2>' + series + '</h2>');
$('#content').append('<blockquote><p>' + description + '</p></blockquote>');
for (var i = 0, l = data.sermons.length; i < l; i++) {
var date, speaker, seriespart, sermon, sermonpart, sermonsubtitle, sermonsubtitlepart, mp3, mp4;
//alert(data.events[i].name);
date = data.sermons[i].date;
// date.js doesn't seem to like the iso8601 time zone offset
var date_readable = Date.parse(date.substring(0, 19)).toString('dddd, MMMM d, yyyy');
speaker = data.sermons[i].speaker;
seriespart = data.sermons[i].seriespart;
sermon = data.sermons[i].sermon;
// replace non-alphanumeric characters with nothing
var sermon_camelcase = sermon.replace(/[^a-zA-Z0-9]+/g, '');
sermonpart = data.sermons[i].sermonpart;
sermonsubtitle = data.sermons[i].sermonsubtitle;
sermonsubtitlepart = data.sermons[i].sermonsubtitlepart;
mp3 = data.sermons[i].downloadlinks.mp3;
mp4 = data.sermons[i].downloadlinks.mp4;
$('#content').append('<h3>Pt. ' + seriespart + ' - ' + sermon + '</h3>');
$('#content').append('<dl id="' + sermon_camelcase + '">');
$('#content #' + sermon_camelcase).append('<dt>Date Preached</dt>');
$('#content #' + sermon_camelcase).append('<dd><time datetime="' + date + '">' + date_readable + '</time></dd>');
$('#content #' + sermon_camelcase).append('<dt>Speaker</dt>');
$('#content #' + sermon_camelcase).append('<dd>' + speaker + '</dd>');
$('#content #' + sermon_camelcase).append('<dt>Download Links</dt>');
$('#content #' + sermon_camelcase).append('<dd id="' + sermon_camelcase + '-downloadlinks">');
$('#content #' + sermon_camelcase + ' #' + sermon_camelcase + '-downloadlinks').append('<ul>');
$('#content #' + sermon_camelcase + ' #' + sermon_camelcase + '-downloadlinks ul').append('<li class="link" onclick="playAudio(\'' + mp3 + '\')">Audio (MP3)</li>');
$('#content #' + sermon_camelcase + ' #' + sermon_camelcase + '-downloadlinks ul').append('<li class="link" onclick="playAudio(\'' + mp4 + '\')">Video (MP4)</li>');
$('#content #' + sermon_camelcase + ' #' + sermon_camelcase + '-downloadlinks').append('</ul>');
$('#content #' + sermon_camelcase).append('</dd>');
$('#content').append('</dl>');
}
});
}
因此,基本上,该页面调用一个 JavaScript 函数,该函数调用 JSON API 并将该数据转换为一堆文本。该文本包含指向播放音频的功能的链接(没有,特别是疯狂)。
有什么明显的,我做错了,或者PhoneGap Media API实际上只需要那么长时间来操作吗?我不这么认为,否则人们会对此感到哗然。我还没有阅读其他关于人们遇到类似问题的报告。
不幸的是,我无法在我的桌面上真正测试它,因为我的浏览器无法访问所有PhoneGap Build的东西(我认为 Build 值得注意,因为存在一些差异)。
还可能值得注意的是,我尝试通过添加到我的 config.xml 来包含媒体插件。<gap:plugin name="org.apache.cordova.media" />
当我更新应用程序时,它给了我这个错误(Unable to create app: plugin unsupported: org.apache.cordova.media
)。该代码是他们在其网站上推荐的。config.xml 使用<gap:plugin name="GAPlugin" />
,所以我也尝试<gap:plugin name="Media" />
过。我遇到了类似的错误(Unable to create app: plugin unsupported: media
)。
我之前没有使用过PhoneGap插件,所以可能是缺少插件导致播放前长时间停顿。我不这么认为,因为这应该是 API 的内置核心功能。