I've implemented the audio record plugin on IOS using phonegap/cordova 1.7. IOS5.1
I'm using it over the standard media.startrecord() function as I want to change the bitrate to reduce the size of the file.
It works fine in the simulator.
On the real iphone it records successfully once but subsequently refuses.. it seems to work but on playback I'm getting an error 4 MediaError.MEDIA_ERR_NONE_SUPPORTED
I've created a new project with just a bare bones record and playback and I'm still getting the same issue.
Here's the test code - It's very basic - just a couple of links to record two separate files and play them back. The setTimeout is there to record just a couple of seconds of audio each time.
I've googled til I've worn out my fingerprints but haven't found a resolution.
Any insight you can give would be very gratefully received.
I'm wondering if I'm failing to close out the recording/playback properly? Or are files referenced differently on the sim v the iPhone?
Many thanks!
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
<meta charset="utf-8">
<link rel="stylesheet" media="only screen and (max-device-width: 480px)" href="iphone.css" type="text/css" />
<script type="text/javascript" charset="utf-8" src="cordova-1.7.0.js"></script>
<script type="text/javascript">
var fs,mediaRec=null, recInterval,recordSettings = {"FormatID": "kAudioFormatULaw","SampleRate": 16000.0,"NumberOfChannels": 1,"LinearPCMBitDepth": 16};
function recfile1() {recordAudio("test.wav");}
function recfile2() {recordAudio("test2.wav");}
function success(){console.log("ok");}
function recordAudio(fname) {
fs.root.getFile(fname, {create: true, exclusive: false}, function(entry){
mediaRec = new Media(entry.fullPath, success, function(){alert("failed");});
mediaRec.startRecordWithSettings(recordSettings);
recInterval = setTimeout(function() {
mediaRec.stopRecordWithSettings();
}, 2000);
}, function(){console.log("error");});
}
function playfile(fname) {
var my_media;
fs.root.getFile(fname, {create: false, exclusive: false},
function success(entry) {
my_media = new Media(entry.fullPath,function(){console.log("ok");},function(err){alert(err.code+" "+err.message);});
my_media.play();
},
function() {
console.log("not found file");
}
);
}
function onBodyLoad() {
document.addEventListener("deviceready", onDeviceReady, false);
}
function onDeviceReady(){
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem){fs=fileSystem;}, function(){console.log("failed");});
Media.prototype.startRecordWithSettings = function(options) {
Cordova.exec(null, null, "AudioRecord","startAudioRecord", [this.id, this.src, options]);
};
Media.prototype.stopRecordWithSettings = function() {
Cordova.exec(null, null, "AudioRecord","stopAudioRecord", [this.id, this.src]);
};
}
</script>
</head>
<body onload="onBodyLoad()">
<a onclick="playfile('test.wav');">play</a>
<a style='margin-top:100px;' onclick="recfile1();">record 1</a>
<a style='margin-top:100px;' onclick="recfile2();">record 2</a>
<a onclick="playfile('test2.wav');">play2</a>
</body>
</html>
Related
I have a problem while loading views using ui-router in cordova ios build. I'm using cordova angular in my application. The ui-router working fine in android build but while i'm running the app using cordova emulate ios the views not getting loaded.
here is my code looks like,
index.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Awesome material design app</title>
<link rel="stylesheet" href="node_modules/angular-material/angular-material.css">
<link rel="stylesheet" href="lib/ionic/css/ionicons.min.css">
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/ngPercentDisplay.css">
<script src="node_modules/angular/angular.js"></script>
<script src="lib/angular-ui-router.min.js"></script>
<script src="node_modules/angular-aria/angular-aria.js"></script>
<script src="node_modules/angular-animate/angular-animate.js"> </script>
<script src="node_modules/angular-material/angular-material.js"></script>
<script src="node_modules/angular-local-storage/dist/angular-local-storage.js"></script>
<script src="lib/angular-touch.min.js"></script>
<script src="js/ng-cordova.min.js"></script>
<script src="cordova.js"></script>
<script src="js/index.js"></script>
<script src="js/controller.js"></script>
<script src="js/router.js"></script>
</head>
<body ng-app="YourApp">
<div layout="column">
<ng-include src="'templates/partials/sidebar.html'" style="top:0px" ng-if ="lang =='ENGLISH'"></ng-include>
<ng-include src="'templates/partials/sidebar-right.html'" style="top:0px" ng-if ="lang =='ARABIC'"></ng-include>
<div ui-view></div>
</div>
</body>
</html>
The router.js file looks like below
app.config(['$urlRouterProvider', '$stateProvider','$compileProvider', function($urlRouterProvider, $stateProvider,$compileProvider) {
$urlRouterProvider.otherwise('/signup');
$stateProvider.state('signup', {
url:'/signup',
templateUrl: 'templates/sign-up.html',
controller: 'signupCtrl'
});
}]);
The index.js file looks like
var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicitly call 'app.receivedEvent(...);'
onDeviceReady: function() {
app.receivedEvent('deviceready');
},
// Update DOM on a Received Event
receivedEvent: function(id) {
var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);
}
};
app.initialize();
controller.js looks like below,
'use strict';
var app = angular.module( 'YourApp', [ 'ngMaterial','ui.router']);
app.controller('myCtrl',['$scope',function ($scope) {
$scope.detail={};
$scope.detail.name="MyApp";
$scope.detail.desc="welcome to my app!";
}]);
Please help me if any one knows about this issue. Thanks in advance.
I am trying to use video.js(gitHub link - https://github.com/videojs/video.js ) plugin in my jquery mobile project to get custom video player, I followed all the documentation from this site (http://videojs.com/), but due to some reasons I am getting following errors -
The element or ID supplied is not valid. (videojs).
this[a] is not a function.
My code -
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="Js/jquery.js"></script>
<script src="Js/jquery.signalR-2.1.2.min.js"></script>
<script src="Js/jquery.mobile-1.4.5.js"></script>
<link href="mcss/jquery.mobile-1.4.5.css" rel="stylesheet" />
<link href="http://vjs.zencdn.net/4.12/video-js.css" rel="stylesheet">
<script src="http://vjs.zencdn.net/4.12/video.js"></script>
<script type="text/javascript">
videojs("Mobile_VIDEO_1").ready(function () {
var vid = this;
vid.on("ended", function () {
alert("is");
$("#videoListXYZ").css("display", "block");
});
});
</script>
</head>
<body>
<div data-role="page" id="p-forget-password">
<div data-role="main" class="ui-content ui-body-cf ui-responsive">
<!-- inserted dyanamically using handlebars template "http://handlebarsjs.com"/ -->
<video id="Mobile_VIDEO_1" class="video-js vjs-default-skin" controls data-id="{{VideoId}}" data-setup='{ "plugins" : { "resolutionSelector" : { "default_res" : "360" } } }' autoplay="autoplay" width="340" height="250">
<source src="{{Path}}" type="video/mp4" data-res="360" />
</video>
</div>
</div>
</body>
Please help me to find out what I am doing wrong.
-I tried using putting videojs(xyx).ready(....) inside document.ready
- I also tried sending my script at the bottom of my page as suggested by (http://help.videojs.com/discussions/problems/985-api-ready-call-fails), but it still not working
After many hit and trial, I realized that my event is firing much before the DOM initialization, so I searched for how to check when the whole page is fully loaded and I come across this document (https://css-tricks.com/snippets/jquery/run-javascript-only-after-entire-page-has-loaded/) from this link I used this
$(window).bind("load", function() {
// code here
});
to check if my page is fully loaded or not . my final solution is mentioned below , if any of you come across a better solution then please share that to help others.
$(window).bind("load", function () {
var videoPath = $('#sv1').attr('src'); //to get the path of video
if (videoPath != "" && videoPath != null) { //checking for non-empty path
console.log(videoPath);
videojs('MY_VIDEO_1', { "plugins": { "resolutionSelector": { "default_res": "360" } } }, function () {
console.log('Good to go!');
this.play();
this.on('ended', function () {
console.log('awww...over so soon?');
$("#videoList").css("display", "block");
});
});
$("#replay").click(function () {
var myPlayer = videojs("MY_VIDEO_1");
myPlayer.play();
});
}
});
I am currently in the process of building an iOS app with ngCordova and Ionic. Part of the specification includes being able to access/play mp3 files stored inside the applications 'www' folder.
After experimenting I have been able to play a music file from an external URL, however when trying to use a locally stored mp3 I am having problems.
Here is the HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="js/ng-cordova.min.js"></script>
<script src="cordova.js"></script>
<script src="js/app.js"></script>
</head>
<body ng-app="editor">
<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title">Editor</h1>
</ion-header-bar>
<ion-content ng-controller="MusicController">
<button class="button" ng-click="play('www/elvis.mp3')">Play</button>
</ion-content>
</ion-pane>
</body>
</html>
And here is the Controller/App:
var editorApp = angular.module('editor', ['ionic', 'ngCordova'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
editorApp.controller("MusicController", function($scope, $cordovaMedia) {
$scope.play = function(src) {
var filePath = cordova.file.applicationDirectory + src;
var iOSPlayOptions = {
numberOfLoops: 2,
playAudioWhenScreenIsLocked : false
};
var media = $cordovaMedia.newMedia(filePath);
media.play(iOSPlayOptions);
};
});
When I "cordova build ios" and run this on a phone in xCode I get the following error:
2015-04-23 11:59:43.619 IonicProject[1487:375698] Unknown resource
'file:///private/var/mobile/Containers/Bundle/Application/FB22B00F-9020-46C9-BBA2-674009BD84F7/IonicProject.app/www/elvis.mp3'
You can use the direct audio tag for iOS app in ionic and no need to do these thing (these are required for Android app). Just write the following code:
HTML Code
<div ng-bind-html="audioCall()"></div>
Controller Code
$scope.audioCall = function () {
if ($scope.audioUrl) {
return $sce.trustAsHtml("<audio controls> <source src='" + $scope.audioUrl + "' type='audio/mpeg'/></audio>");
} else {
return "";
}
};
Has anybody else had any similar experience?
I have this app working fine on Android, but in iOS the online/offline events are not firing.
As far as I know I have everything set up correctly, and I can even use the 'FileTransfer' plugin, but my online/offline event handlers are not being called.
With the following test app:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Test</title>
<script charset="utf-8" src="js/cordova.js"></script>
<script>
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
console.log("Device is ready!");
document.addEventListener("online", onOnline, false);
document.addEventListener("offline", onOffline, false);
}
function onOnline() {
console.log("Device is online!");
}
function onOffline() {
console.log("Device is offline");
}
</script>
</head>
<body>
</body>
</html>
I get 'Device is ready!' reported to the console, but beyond that I get nothing.
Any suggestions?
I got it to work by putting the event listeners above the on device ready.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Test</title>
<script charset="utf-8" src="js/cordova.js"></script>
<script>
document.addEventListener("deviceready", onDeviceReady, false);
document.addEventListener("online", onOnline, false);
document.addEventListener("offline", onOffline, false);
// PhoneGap is loaded and it is now safe to make calls PhoneGap methods
//
function onDeviceReady() {
console.log("Device Ready");
}
// Handle the online event
//
function onOnline() {
console.log("Online");
}
function onOffline() {
console.log("Offline");
}
</script>
</head>
<body>
</body>
</html>
I'm trying to create a PhoneGap application for Android and iOS.
So far I've been succeeding to the extent that I've been able to access the LocalFileSystem on Android 2.2 and up.
On iOS (5 and 6), I've had no such luck unfortunately.
The FileReader and FileWriter examples fail to work as well.
I've spent some time debugging this using jsconsole.com and as far as I can tell window.requestFileSystem and window.webkitRequestFileSystem are both undefined.
Which would explain why I have issues with the file system.
I'm using Cordova 2.2.0 and XCode 4.5 for the iOS part.
Both the example and my own code is working on Android.
If any of you have any advice I'd really appreciate the positive effect it will have on my mental health!
Edit:
index.html:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
<title>Hello World</title>
</head>
<body>
<div class="app">
click!
</div>
<script type="text/javascript" src="cordova-2.2.0.js"></script>
<script type="text/javascript" src="js/jquery-1.8.2.min.js"></script>
<script src="http://jsconsole.com/remote.js?secret-debug-key"></script>
<script type="text/javascript" src="js/filesystem.js"></script>
<script type="text/javascript">
var myfs;
document.addEventListener('deviceready', function() {
myfs = new FS();
myfs.initializeFileSystem();
});
</script>
</body>
</html>
filesystem.js:
var FS = (function()
{
var self = {};
self.initializeFileSystem = function()
{
window.requestFileSystem = window.webkitRequestFileSystem || window.requestFileSystem;
window.requestFileSystem(1, 0, self.gotFS, self.fail);
};
self.gotFS = function (fileSystem)
{
window.rootFS = fileSystem.root;
//create our cache directory if it does not exist
var entry = fileSystem.root;
entry.getDirectory("tempdirectory", {create: true, exclusive: false}, function() {console.log("directory already present or created");}, function(error) {console.log("Error creating directory " + error.code);});
};
self.fail = function()
{
console.log("requestFileSystem failed");
};
self.downloadImage = function(url, fileName, callback)
{
var ft = new FileTransfer();
var filename = fileName;
var callback = callback;
ft.download(
url,
window.rootFS.fullPath + "/" + filename,
function(entry)
{
if(callback!= undefined)
{
callback(entry);
}
},
function(error)
{
console.log("download error: " + error.code);
}
);
};
self.clicked = function()
{
//random test URL
var url = "http://www.embeddedpeople.dk/_/rsrc/1301663383918/home/ydelser/konsulentydelser/test/test.png?height=400&width=350";
self.downloadImage(url, "test.png", function(){console.log("download succesful");$('body').append('<img src="file:///data/data/dk.attention8.filesystem/test.png" />');});
return false;
};
return self;
}
);
This works on Android, after the click has been made, the file is downloaded and an img tag containing a reference to the path of the downloaded image should be inserted in the DOM.
I'm aware that this path isn't valid on iOS nor the correct one on a device with an SDcard, but the issue is occuring before this img tag is added.
This image should show that the javascript code works in Android ( taken of the Android Emulator ).
If you need further clarification or have questions I'll provide them as fast as I can.
Thank you for your time!
I've finally resolved this issue.
I've had a common "www" folder that I'd transfer from my Android to my iOS project.
I've naively overwritten the entire www folder, and this has been causing the problem.
The cordova.js file in the root of the www folder is platform specific, and I had thusly used the Android cordova.js file in my iOS project, which obviously wasn't working.
Thank you to fmertz on #phonegap for pointing me in the right direction.