video.js not working properly with jquery mobile - jquery-mobile

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();
});
}
});

Related

Accessing mp3 files stored inside ngCordova/ionic iOS app

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 "";
}
};

Phonegap + Jquery Mobile: initialization / registration best practices

I am developing an Phonegap (3.3.0) + Jquery Mobile (1.4) app.
I get an infinite loading page (white page with ui-loader icon). This is erratic and sometimes the app starts well.
I see a very strange bug: none of the first "console.logs" I use in my js file are displayed in the Phonegap Build Weinre debug console.
Only after a certain line (which contain by the way the first asynchronous function) the console.log are displayed in the Weinre console.
So I guess I have a binding order problem related to Jquery Mobile and Phonegap, but I can't find what's wrong in my initialization.
Can I be also due to the order in which I call js files in my index.html ?
I followed this post to register Phonegap and JQM : Correct way of using JQuery-Mobile/Phonegap together?
recommended here : jQuery Mobile : What is the order of page events triggering?
by #Gajotres.
Can you help ?
Thanks
HTML:
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
<!-- SPLASH PAGE -->
<div id="splash-page" data-role="page">
<div class='toastenjs' style='display:none'></div>
<center id="splashLogoCenter">
<img src="images/splash.png" width="200" />
</center>
</div>
<!-- WELCOME PAGE -->
<div id="welcome-page" data-role="page">
...
</div>
<script src="js/jquery-1.9.1.js"></script>
<script src="js/jquery.jsonp-2.4.0.min.js"></script>
<script src="js/functions.js"></script>
<script src="js/functionCUgly.js"></script>
<script src="js/boardDims.js"></script>
<script src="phonegap.js"></script>
<script src="js/jquery.mobile.config.js"></script>
<script src="js/jquery.mobile-1.4.3.min.js"></script>
<!--POUCHDB -->
<script src="js/pouchdb-2.2.3.min.js"></script>
<!-- Flexslider-->
<!-- <script src="js/flexslider-v2.js"></script>--> <!-- v2.2 doesn't work, maybe because we're not using last versions of jquery and jqm -->
<script src="js/flexsliderV2.3.js"></script>
<!-- iScroll-->
<script type="application/javascript" src="js/iscroll.js"></script>
<script type="application/javascript" src="js/jquery.mobile.iscrollview.js"></script>
<!-- Add2home : create a shortcut icon of the wep app on the phone homescreen -->
<script type="application/javascript" src="js/add2home.js"></script>
<script src="js/GoogleLogin.js"></script> <!--Phonegap module by eric valenzia https://github.com/valenzia10/PhonegapGoogleLogin-->
<script src="js/jquery.ddslick.min.js"></script>
<script src="js/jquery-geturlvar.js"></script>
<script src="js/html2canvas.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
if (typeof(google) != 'undefined'){
google.load('visualization', '1.0', {'packages':['corechart']});
}
</script>
JS file:
var deviceReadyDeferred = $.Deferred();
var jqmReadyDeferred = $.Deferred();
$(document).one("mobileinit", function () {
console.log('mobileinit just fired'); //this one is not displayed in the weinre console
jqmReadyDeferred.resolve();
});
if ( isPhoneGap() ) {
document.addEventListener("deviceReady", onDeviceReady, false);
function onDeviceReady() {
deviceReadyDeferred.resolve();
}
$.when(deviceReadyDeferred, jqmReadyDeferred).then( EVERYTHING() ); // !!!!! normalement il faut virer ces parenthèses pour respecter le $.when....mais ça fait tout bugger !!!!!!!!!
} else {
console.log("NOT Running on PhoneGap!");
$.when(jqmReadyDeferred).then( EVERYTHING );
}
function EVERYTHING() {
console.log("on est entré dans EVERYTHING()"); //not displayed in the weinre console
insideEVERYTHING = 1;
console.log("jqmReadyDeferred is "+jqmReadyDeferred.state()); //not displayed in the weinre console
console.log("deviceReadyDeferred is "+deviceReadyDeferred.state()); //not displayed in the weinre console
//FOR EVERY PAGE
$(document).on('pagecontainershow', function (e, ui) {
//...
});
$(document).on('pagecontainershow', function (e, ui) {
//...
});
// --------------- SPLASH PAGE ---------------------
//$(document).on('pagecreate','#splash-page', function(){
$(document).on('pagecontainershow', function (e, ui) {
var activePageId = $(':mobile-pagecontainer').pagecontainer('getActivePage').attr('id');
if (activePageId === 'splash-page') {
console.log("we are in splash-page");
if (typeof debugOptionUseLocalDB != 'undefined' && debugOptionUseLocalDB) {
fallbackToLocalDBfile();
console.log('on yess');
}else{
if(connectionStatus == 'online'){
console.log("launching getJsonpFile...");
//DEBUG TIMER
var time=[];
var dummy;
dummy = new Date().getTime();
time.push(dummy);
getJsonpFile(dbUrl())
.done(function(data) {
console.log("...getJsonpFile done.");
if(localStorage) {
if ( isPhoneGap() || !isIOS() ) { //BUG iOS safari doesn't work with this (Cf. Philippe's ipad), si on est sur phonegap ok, si on n'est pas sur phonegap et pas sur iOS ok
localStorage.setItem("proDB", JSON.stringify(data)); //write to localStorage
}
}
//...JQM bindings are continued below
The best registration is the following :
var isPhoneGap;
var deviceReadyDeferred = $.Deferred();
var jqmReadyDeferred = $.Deferred();
isPhoneGap = checkIfPhoneGap();
if ( isPhoneGap ) {
$.when(deviceReadyDeferred, jqmReadyDeferred).done( Everything );
} else {
console.log("NOT Running on PhoneGap!");
$.when(jqmReadyDeferred).done( Everything );
}
$(document).on("mobileinit", function () {
//alert('mobileinit just fired');
//popShortToast("mobileinit just fired");
jqmReadyDeferred.resolve();
});
document.addEventListener("deviceReady", onDeviceReady, false);
function onDeviceReady() {
//popShortToast("deviceReady just fired");
deviceReadyDeferred.resolve();
}
function checkIfPhoneGap() {
var app = document.URL.indexOf( 'http://' ) === -1 && document.URL.indexOf( 'https://' ) === -1; // && document.URL.indexOf( 'file://' );
if ( app ) {
return true;
} else {
return false;
}
}
function Everything() {
//enter your JQM bindings here, and use Phonegap's features
}

Jquery Mobile pageshow event firing twice

I currently have a mobile site I am building and I am having trouble with integrating a custom JQuery widget. For some reason the the pageshow event is firing twice for whichever page is loaded first.
For ease of understanding I have created two HTML pages
Page 1
<!doctype html>
<head>
<meta charset="utf-8">
<title>One</title>
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.min.css" />
<script type="text/javascript" src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script type="text/javascript">
$(document).on("mobileinit", function () {
$.mobile.changePage.defaults.reloadPage = true;
});
</script>
<script type="text/javascript" src="https://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.js"></script>
</head>
<body id="default">
<div data-role="page" id="content-one">
<div role="main" class="ui-content" id="one-content">
One<br/>
back to two
</div>
<script type="text/javascript">
(function($, undefined) {
$.widget("test.stuff", {
_create : function() {
console.log("create");
},
_init : function() {
console.log("_init");
},
destroy: function () {
this.element.empty();
$.Widget.prototype.destroy.call(this);
}
});
})(jQuery);
</script>
<script type="text/javascript">
$(document).on("pageshow", "#content-one", function () {
console.log("pageshow1");
$("#content-one").stuff({});
});
$(document).on("pagebeforeshow", "#content-one", function () {
console.log("pagebeforeshow1");
});
</script>
</div>
</body>
</html>
Page 2
<!doctype html>
<head>
<meta charset="utf-8">
<title>Two</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.10.2.min.js"> </script>
<script type="text/javascript">
$(document).on("mobileinit", function () {
$.mobile.changePage.defaults.reloadPage = true;
});
</script>
<script type="text/javascript" src="https://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.js"></script>
</head>
<body id="default">
<div data-role="page" id="content-two">
<div role="main" class="ui-content">
Two<br/>
back to one
</div>
<script type="text/javascript">
$(document).on("pageshow", "#content-two", function () {
console.log("pageshow2");
});
$(document).on("pagebeforeshow", "#content-two", function () {
console.log("pagebeforeshow2");
});
</script>
</div>
</body>
</html>
To recreate load page one first, navigate to page two using link, then navigate to page one using link.
When page one is loaded again the pageshow event is fired twice. I have the reloadPage set to true as I have dynamic content for my pages and I cannot serve cached pages.
I very well could be using the events incorrectly.
Try substituting your $(document).on("pageshow",...) with $(document).one("pageshow", ...), which restricts the event to one call http://api.jquery.com/one/.
The problem is that using on in the inline script creates a new event each time the page is loaded. So the first time you load the page, the inline script is executed and the pageshow event is triggered. The second time a new event is triggered again, but the first one is still listening to content-one pageshow. In fact, if you repeat the process you'll see the log three, four, ... times.
Another option could be to create a script in the head section which sets up all required triggers in $(document).on("pageshow", "#content-one", ...), $(document).on("pageshow", "#content-two", ...). In this case, the script will only be initialized once, so it will work.
Wasted about 2 hours trying to do all the fixes on here and other sites. I gave up and put an if statement in their to prevent it from firing again
var hasDownload = false;
$(document).on("pageinit", "#mypage",function(event){
if (hasDownload === false) {
hasDownload = true;
// do some work
}
);
Try to remove the page on hide event, like so :
$(document).on("mobileinit", function () {
$.mobile.changePage.defaults.reloadPage = true;
$(docuement).on('pagehide', function (event, ui) {
$(event.target).remove();
});
});
Remenber that if you don't disable ajax, all request will be with AJAX

Reload Ajax Tab with jquery UI 1.9+

While their are plenty of posts regarding reloading a jQueryUI tab via the load method, I can't seem to make it work in 1.9+. I wish I could see a way to show this in a fiddle, but as I don't... note that the refresh button/function works every time in the following nested tabs set-up under 1.8+ but works only once under 1.9+, and fails after that. In context, (loading dynamic content via php under wordpress) it doesn't work at all. According to the ajaxStart()ajaxStop() function calls, an ajax call is made every time the refresh button is clicked, however the content (watch the date/time under tab E or tab A/sub parent E) is only reloaded on the first click of the #refresh button, which fails to re-load the tab content on subsequent clicks.
stye.css
div.clear { clear:both; }
#refresh { position: relative; top:-40px; left:300px; }
#loading
{ display:none;
position: absolute;
top:100px;
left:300px;
font-size: 200%;
z-index:1001;
border:3px solid green;
background:#ffffff;
}
tabs.js
jQuery(function()
{ set_tabs();
jQuery('body').on("click", "#refresh", function()
{ jQuery('.tabset ul li a').each(function()
{ var link = jQuery(this);
var tab = link.parent();
var tabset = link.closest('div.tabset');
if(tabset.is(':visible') && tab.hasClass('ui-state-active')) index = link.text().replace(/ /g, '_');
});
jQuery(".tabset").tabs( "load" , index );
});
jQuery("#loading").ajaxStart(function() {jQuery(this).show();});
jQuery("#loading").ajaxStop(function(){ jQuery(this).fadeOut(1500); });
});
function set_tabs()
{ jQuery('.tabset').tabs({ cache:true }); }
index.html
<!--script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
<link type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.17/themes/smoothness/jquery-ui.css" rel="stylesheet"-->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js"></script>
<link type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/themes/smoothness/jquery-ui.css" rel="stylesheet">
<script type="text/javascript" src="tabs.js"></script>
<link type="text/css" href="style.css" rel="stylesheet" />
<div id="parentTabSet" class="tabset">
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
<li>E</li>
</ul>
<input type='button' id='refresh' value='refresh' />
<div id='loading'>Loading...</div>
<div id="A" class="tabset">
<ul>
<li>A_1</li>
<li>A_2</li>
<li>parent E</li>
</ul>
<div id="A_1"><p>A_1 - FOO</p></div>
<div id="A_2"><p>A_2 - BAR</p></div>
</div>
<div id="B"><p>Div B</p></div>
<div id="C"><p>Div C</p></div>
<div id="D"><p>Div D</p></div>
</div>
tabs_e.html
<script>
jQuery( function()
{ set_tabs();
var d = new Date();
jQuery('#E_1 p').text(d);
jQuery('#E_2 p').text(d);
});
</script>
<div class="tabset">
<ul>
<li>E_1</li>
<li>E_2</li>
</ul>
<div id="E_1"><p>E_1 - BAR</p></div>
<div id="E_2" class='clear'><p>E_2 - BAZ</p></div>
</div>
The .live() function has been deprecated for a while now, and support is completely gone in jQuery 1.9+. Use this:
$(document).on("click", "#refresh", function() {
// your current "live" code
});
So it turns out that not only has the cache option been deprecated in 1.9+ it's legacy behavior has been altered such that (if used) the load method will not reload the tab content.
The approach I've come up with is -- I think -- an abomination which I'm hoping some one might provide a cleaner alternative to. (oh pleeeaazzz!) Anyway, FWIW... here's what I came up with.
tabs.js (revisited)
jQuery(function()
{ set_tabs();
jQuery(document).on("click", "#refresh", function()
{ refresh = {};
refresh.tab = true;
jQuery('.tabset ul li a').each(function()
{ var link = jQuery(this);
var tab = link.parent();
var tabset = link.closest('div.tabset');
if(tabset.is(':visible') && tab.hasClass('ui-state-active')) index = link.text().replace(/ /g, '_');
});
jQuery(".tabset").tabs( "load" , index );
});
jQuery("#loading").ajaxStart(function() {jQuery(this).show();});
jQuery("#loading").ajaxStop(function(){ jQuery(this).fadeOut(1500); });
});
function set_tabs()
{ jQuery('.tabset').tabs(
{ beforeLoad: function( event, ui)
{ if(typeof refresh.tab =='undefined')
{ if ( ui.tab.data( "loaded" ))
{ event.preventDefault();
return;
}
ui.jqXHR.success(function() { ui.tab.data( "loaded", true );});
} else refresh={};
}
});
}

cordova 1.7 iOS audiorecord plugin

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>

Resources