Instascan select camara to scan qr - html

My website reads QR CODES using the mobile phone. I have used that library
https://github.com/schmich/instascan
<div class="select">
<label for="videoSource">Video source: </label><select id="videoSource"></select>
</div>
<video autoplay muted playsinline></video>
<script async src="js/main.js"></script>
Because the mobile phone has many camaras I want to let the user to select which camara wants for scanning the qr code.
main.js:
https://simpl.info/getusermedia/sources/
https://github.com/samdutton/simpl/blob/gh-pages/getusermedia/sources/js/main.js
'use strict';
var videoElement = document.querySelector('video');
var videoSelect = document.querySelector('select#videoSource');
videoSelect.onchange = getStream;
getStream().then(getDevices).then(gotDevices);
function getDevices() {
// AFAICT in Safari this only gets default devices until gUM is called :/
return navigator.mediaDevices.enumerateDevices();
}
function gotDevices(deviceInfos) {
window.deviceInfos = deviceInfos; // make available to console
console.log('Available input and output devices:', deviceInfos);
for (const deviceInfo of deviceInfos) {
const option = document.createElement('option');
option.value = deviceInfo.deviceId;
if (deviceInfo.kind === 'videoinput') {
option.text = deviceInfo.label || `Camera ${videoSelect.length + 1}`;
videoSelect.appendChild(option);
}
}
}
function getStream() {
if (window.stream) {
window.stream.getTracks().forEach(track => {
track.stop();
});
}
const videoSource = videoSelect.value;
const constraints = {
video: {deviceId: videoSource ? {exact: videoSource} : undefined}
};
return navigator.mediaDevices.getUserMedia(constraints).
then(gotStream).catch(handleError);
}
function gotStream(stream) {
window.stream = stream; // make stream available to console
videoSelect.selectedIndex = [...videoSelect.options].
findIndex(option => option.text === stream.getVideoTracks()[0].label);
videoElement.srcObject = stream;
}
function handleError(error) {
console.error('Error: ', error);
}
Then I want to start the scanner to the camara the user has selected because I want to obtaint the QR-CODE:
<script type="text/javascript">
let scanner = new Instascan.Scanner({ video: document.getElementById('preview'),mirror: false });
scanner.addListener('scan', function (content) {
alert("qr result " + content);
});
Instascan.Camera.getCameras().then(function (cameras) {
if (cameras.length > 0) {
scanner.start(cameras[0]); //I want to scanner.start the camara that the user has selected.
} else {
console.error('No cameras found.');
}
}).catch(function (e) {
console.error(e);
});
</script>

Related

Viewer automatically change material to default

I have a problem with changes of material of some elements
when geometry is loaded:
_this.viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, () => {
changeModelMaterial()
});
...
const changeModelMaterial = () => {
const grey = new THREE.Color(0.5, 0.5, 0.5);
let dbIds = getDbIds()
changeAllElementsMaterial(grey)
setMaterialOfDbIds(dbIds)
}
code that i`m using to change material:
const changeAllElementsMaterial = (color) => {
const fragmentList = _this.viewer.model.getFragmentList();
for (let materialId of fragmentList.materialids) {
if (fragmentList.materialmap[materialId]) {
fragmentList.materialmap[materialId].map = null
fragmentList.materialmap[materialId].color = color
fragmentList.materialmap[materialId].needsUpdate = true;
}
}
_this.viewer.impl.invalidate(true);
}
const setMaterialOfDbIds = (dbIds) => {
var color_diffuse = 0xAB00EE;
var color_specular = 0xEEABEE;
var colorM = new THREE.MeshPhongMaterial({
color: color_diffuse,
specular: color_specular
});
_this.viewer.impl.matman().addMaterial(
'ADN-Material-' +
"common color material", // or a GUID
colorM,
true);
for (let dbId of dbIds) {
_this.viewer.model.getData().instanceTree.enumNodeFragments(dbId, function (fragId) {
_this.viewer.model.getFragmentList().setMaterial(fragId, colorM);
});
}
_this.viewer.impl.invalidate(true);
}
It works, because I see that materials of model are changed, but the problem is that materials back to default after ~1-2 sec.
After this I cannot change material even with run this code manually.
Question is why Viewer is locking material change after this 2 sec, how to prevent it
And maybe you will be able to tell me what i can do better with material changes, eg. maybe something better that running my code after GEOMETRY_LOAD. The best would be change material before first render of model
........
hint:
when change event from GEOMETRY_LOADED_EVENT to OBJECT_TREE_CREATED_EVENT "sometimes" but only sometimes it works well (materials stay to the end of working with model), but mostly when i run my method after OBJECT_TREE_CREATED it not working (even not working by run it manually, materials are in some way locked). So I suspect that problem is between time of GEOMETRY_LOAD and OBJECT_TREE_CREATED
I will be grateful for any help
==============================full code==============================
index.html
<div id="main">
<div id="MyViewerDiv"></div>
<button id="open-nav-button" onClick="showDocInfo()">test</button>
</div>
<script src="https://developer.api.autodesk.com/derivativeservice/v2/viewers/three.min.js"></script>
<script src="https://developer.api.autodesk.com/derivativeservice/v2/viewers/viewer3D.min.js"></script>
<script type="text/javascript" src="lib/jquery.min.js"></script>
<script src="js/autodesk-viewer.js"></script>
<script src="js/extension/test-extension.js"></script>
<script>
const autodeskViewer = new AutodeskViewer()
const showDocInfo = () => {
autodeskViewer.showDocInfo()
}
</script>
autodesk-viewer.js
var AutodeskViewer = (function () {
function AutodeskViewer() {
var _this = this;
this.urn = 'urn:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6Zm9yZ2UtamF2YS1zYW1wbGUtYXBwLTFzcGduazdqcWpxdjhmYXV0YmNzd2R0cGdvN3VtNWY1L1BPQy1Gb3JnZS1JVCUyMDIwMTclMjBSdWNoXzEwMDUxNy5ud2Q';
this.initializeViewer = function (containerId, documentId) {
_this.viewerApp = new Autodesk.Viewing.ViewingApplication(containerId);
var config = {
extensions: ['TestExtension']
};
_this.viewerApp.registerViewer(_this.viewerApp.k3D, Autodesk.Viewing.Private.GuiViewer3D, config);
_this.viewerApp.loadDocument(documentId, _this.onDocumentLoadSuccess, _this.onDocumentLoadFailure);
}
this.onDocumentLoadSuccess = function (doc) {
const viewables = _this.viewerApp.bubble.search(av.BubbleNode.MODEL_NODE);
if (viewables.length === 0) {
return;
}
_this.viewerApp.selectItem(viewables[0].data, _this.onItemLoadSuccess, _this.onItemLoadFail);
_this.viewer3d = _this.viewerApp.getCurrentViewer();
}
this.onDocumentLoadFailure = (viewerErrorCode) => {}
this.onItemLoadSuccess = (viewer) => {
_this.viewer = viewer
}
this.onItemLoadFail = (errorCode) => {}
this.initialize = () => {
var options = {
env: 'AutodeskProduction',
getAccessToken: _this.getToken,
refreshToken: _this.getToken
};
Autodesk.Viewing.Initializer(options, _this.initCallback);
};
this.initCallback = function () {
_this.initializeViewer('MyViewerDiv', _this.urn, '3d');
};
this.getToken = function (onGetAccessToken) {
$.get("forge/oauth/token")
.done(function (data) {
token = data
onGetAccessToken(token, 60 * 60);
})
.fail(function (error) {
console.log('ERROR', error);
});
};
this.showDocInfo = function () {};
this.initialize();
}
return AutodeskViewer;
}());
test-extension.js
var _self;
var _viewer;
var _tempValue = 0;
function TestExtension(viewer, options) {
Autodesk.Viewing.Extension.call(this, viewer, options);
_self = this;
_viewer = viewer;
}
const changeModelMaterial = () => {
// _tempValue++;
// if (_tempValue == 2) {
const elements = [4340, 4342, 4344, 4346, 4348, 4367, 4371, 4375, 4380, 4452, 4468, 4488, 4503, 4517, 4520, 4522, 4524, 4526, 4528, 4530]
changeAllElementsMaterial(new THREE.Color(0.5, 0.5, 0.5))
setMaterialOfDbIds(elements)
_tempValue = 0
// }
}
const changeAllElementsMaterial = (color) => {
var fragmentList = _viewer.model.getFragmentList();
for (let materialId of fragmentList.materialids) {
if (fragmentList.materialmap[materialId]) {
fragmentList.materialmap[materialId].map = null
fragmentList.materialmap[materialId].color = color
fragmentList.materialmap[materialId].needsUpdate = true;
}
}
_viewer.impl.invalidate(true);
}
const setMaterialOfDbIds = (dbIds) => {
var colorM = new THREE.MeshPhongMaterial({
color: new THREE.Color(0xAB00EE)
});
for (let dbId of dbIds) {
_viewer.model.getData().instanceTree.enumNodeFragments(dbId, function (fragId) {
_viewer.model.getFragmentList().setMaterial(fragId, colorM);
});
}
_viewer.impl.invalidate(true);
}
TestExtension.prototype = Object.create(Autodesk.Viewing.Extension.prototype);
TestExtension.prototype.constructor = TestExtension;
TestExtension.prototype.load = function () {
_viewer.addEventListener(Autodesk.Viewing.OBJECT_TREE_CREATED_EVENT, changeModelMaterial)
// _viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, changeModelMaterial)
return true
};
TestExtension.prototype.unload = function () {
return true
};
Autodesk.Viewing.theExtensionManager.registerExtension('TestExtension', TestExtension);
I found the solution, quite accidentally... from other thing i tried to do
before:
const setMaterialOfDbIds = (dbIds) => {
var color_diffuse = 0xAB00EE;
var color_specular = 0xEEABEE;
var colorM = new THREE.MeshPhongMaterial({
color: color_diffuse,
specular: color_specular
});
_this.viewer.impl.matman().addMaterial("common color material", colorM, true);
for (let dbId of dbIds) {
_this.viewer.model.getData().instanceTree.enumNodeFragments(dbId, function (fragId) {
_this.viewer.model.getFragmentList().setMaterial(fragId, colorM);
});
}
_this.viewer.impl.invalidate(true);
}
after
const setMaterialOfDbIds = (dbIds) => {
var color_diffuse = 0xAB00EE;
var color_specular = 0xEEABEE;
var colorM = new THREE.MeshPhongMaterial({
color: color_diffuse,
specular: color_specular
});
_this.viewer.impl.matman().addMaterial("common color material", colorM, true);
for (let dbId of dbIds) {
_this.viewer.model.getData().instanceTree.enumNodeFragments(dbId, function (fragId) {
_this.viewer.model.getFragmentList().setMaterial(fragId, colorM);
var fragProxy = _this.viewer.impl.getFragmentProxy(_this.viewer.model, fragId)
fragProxy.updateAnimTransform()
});
}
_this.viewer.impl.invalidate(true);
}
Really I don`t know why adding
var fragProxy = _this.viewer.impl.getFragmentProxy(_this.viewer.model, fragId)
fragProxy.updateAnimTransform()
made the difference, i didn`t saw anything like that in any example of updating material.
What is interesting this code is running for only few elements in model, but it works for even those elements that materials changed before (in changeAllElementsMaterial method).
#Philippe Leefsma if you understand it pls tell something more why it works
So far I cannot reproduce the issue on my side, I am using the following code (ES7) extracted from that extension: Viewing.Extension.Material
createColorMaterial (color) {
const material = new THREE.MeshPhongMaterial({
specular: new THREE.Color(color),
side: THREE.DoubleSide,
reflectivity: 0.0,
color
})
const materials = this.viewer.impl.getMaterials()
materials.addMaterial(
this.guid(),
material,
true)
return material
}
async onModelCompletedLoad() {
const material = this.createColorMaterial(0xFF0000)
const model = this.viewer.model
const fragIds = await Toolkit.getFragIds(model)
fragIds.forEach((fragId) => {
model.getFragmentList().setMaterial(
fragId, material)
})
this.viewer.impl.sceneUpdated(true)
}
The onModelCompletedLoad is a custom event fired when both GEOMETRY_LOADED_EVENT and OBJECT_TREE_CREATED_EVENT have been fired.
Take a look at this article for more details: Asynchronous viewer events notification
I doubt you can easily change the materials before the model is first rendered, however you could use a custom overlay that hides the model until your custom logic has performed all required steps, this is the approach I am using in my demos at: https://forge-rcdb.autodesk.io/configurator
After loading a model, all custom materials are being persisted fine:
The material extension can be tested live from there.
Hope that helps

Primefaces PhotoCam Camera Selection

how could I enable camera selection on primefaces photocam ?
Here is what I have done presently without luck ( image not rendering... )
<pm:content>
<script>
jQuery(document).ready(function() {
'use strict';
var videoElement = document.querySelector('video');
var videoSelect = document.querySelector('select#videoSource');
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
function gotSources(sourceInfos) {
for (var i = 0; i !== sourceInfos.length; ++i) {
var sourceInfo = sourceInfos[i];
var option = document.createElement('option');
option.value = sourceInfo.id;
if (sourceInfo.kind === 'audio') {
} else if (sourceInfo.kind === 'video') {
option.text = sourceInfo.label || 'camera ' + (videoSelect.length + 1);
videoSelect.appendChild(option);
} else {
console.log('Some other kind of source: ', sourceInfo);
}
}
}
if (typeof MediaStreamTrack === 'undefined' ||
typeof MediaStreamTrack.getSources === 'undefined') {
alert('This browser does not support MediaStreamTrack.\n\nTry Chrome.');
} else {
MediaStreamTrack.getSources(gotSources);
}
function successCallback(stream) {
window.stream = stream; // make stream available to console
videoElement.src = window.URL.createObjectURL(stream);
videoElement.play();
}
function errorCallback(error) {
console.log('navigator.getUserMedia error: ', error);
}
function start() {
videoElement = document.querySelector('video');
if (!!window.stream) {
videoElement.src = null;
window.stream.stop();
}
var videoSource = videoSelect.value;
var constraints = {
audio: false,
video: {
optional: [{
sourceId: videoSource
}]
}
};
navigator.getUserMedia(constraints, successCallback, errorCallback);
}
videoSelect.onchange = start;
start();
});
</script>
<p:outputLabel value="Seleccione Camara:" />
<select id="videoSource"></select>
<p:photoCam widgetVar="pc" listener="#{eventoMB.oncapture}" update="photo" />
I am trying to achieve this goal by using javascript but the problem something is preventing the change proposed here, which I could not identify up to know...
Thanks for your attention.
Well in case someone needs this information:
in attach function(c) after these lines ( around line 89 from primefaces-5.2.jar\META-INF\resources\primefaces\photocam\photocam.js ) :
b.style.transform = "scaleX(" + h + ") scaleY(" + g + ")"
}
c.appendChild(b);
I added the following lines:
var constraints = {
audio: false,
video: {
facingMode: {
exact: "environment"
}
}
};
this.video = b;
var i = this;
navigator.getUserMedia(constraints, function(j) {
Note that specifing facingMode for the video constraints apparently does the trick in firefox for android and google only in the desktop version apparently as stated here:
GetUserMedia - facingmode
By the way it would be interesting to me to discuss if this solution is the more appropiate thing to do or there is a better one.
Hope this helps someone else, thanks anyway.

Local store video webRTC

I used the the information from the link (here) and got the following code, which helps me to record a video with my webcam. The code allows me to record a video and makes it available to download. However, I want to save the recorded video automatically to a local folder. How can I do that?
<script src="https://cdn.webrtc-experiment.com/RecordRTC.js"></script>
<section class="experiment">
<div class="inner">
<button style="float: right;" id="fit-to-screen">Fit to Screen!</button>
<label for="canvas-width-input">Canvas Width</label>
<input type="text" id="canvas-width-input" value="320">
<br />
<label for="canvas-height-input">Canvas Height</label>
<input type="text" id="canvas-height-input" value="240">
<br />
<div>
<button id="record-video">Record</button>
<button id="pause-resume-video" disabled>Pause</button>
<button id="stop-recording-video" disabled>Stop</button>
<hr>
<h2 id="video-url-preview"></h2>
<br>
<input type="checkbox" id="record-screen" style="width:auto;">
<label for="record-screen">Record Screen</label>
<br>
<video id="video" autoplay loop controls muted></video>
</div>
</div>
</section>
<script>
(function() {
var params = {},
r = /([^&=]+)=?([^&]*)/g;
function d(s) {
return decodeURIComponent(s.replace(/\+/g, ' '));
}
var match, search = window.location.search;
while (match = r.exec(search.substring(1)))
params[d(match[1])] = d(match[2]);
window.params = params;
})();
</script>
<script>
function getByID(id) {
return document.getElementById(id);
}
var recordVideo = getByID('record-video'),
pauseResumeVideo = getByID('pause-resume-video'),
stopRecordingVideo = getByID('stop-recording-video');
var canvasWidth_input = getByID('canvas-width-input'),
canvasHeight_input = getByID('canvas-height-input');
if(params.canvas_width) {
canvasWidth_input.value = params.canvas_width;
}
if(params.canvas_height) {
canvasHeight_input.value = params.canvas_height;
}
var video = getByID('video');
var videoConstraints = {
audio: false,
video: {
mandatory: {},
optional: []
}
};
</script>
<script>
var screen_constraints;
function isCaptureScreen(callback) {
if (document.getElementById('record-screen').checked) {
document.getElementById('fit-to-screen').onclick();
getScreenId(function (error, sourceId, _screen_constraints) {
if(error === 'not-installed') {
window.open('https://chrome.google.com/webstore/detail/screen-capturing/ajhifddimkapgcifgcodmmfdlknahffk');
}
if(error === 'permission-denied') {
alert('Screen capturing permission is denied.');
}
if(error === 'installed-disabled') {
alert('Please enable chrome screen capturing extension.');
}
if(_screen_constraints) {
screen_constraints = _screen_constraints.video;
videoConstraints = _screen_constraints;
}
else {
videoConstraints = screen_constraints;
}
callback();
});
}
else {
callback();
}
}
recordVideo.onclick = function() {
isCaptureScreen(function() {
recordVideoOrGIF(true);
});
};
function recordVideoOrGIF(isRecordVideo) {
navigator.getUserMedia(videoConstraints, function(stream) {
video.onloadedmetadata = function() {
video.width = canvasWidth_input.value || 320;
video.height = canvasHeight_input.value || 240;
var options = {
type: isRecordVideo ? 'video' : 'gif',
video: video,
canvas: {
width: canvasWidth_input.value,
height: canvasHeight_input.value
},
disableLogs: params.disableLogs || false,
recorderType: null // to let RecordRTC choose relevant types itself
};
recorder = window.RecordRTC(stream, options);
recorder.startRecording();
video.onloadedmetadata = false;
};
video.src = URL.createObjectURL(stream);
}, function() {
if (document.getElementById('record-screen').checked) {
if (location.protocol === 'http:')
alert('<https> is mandatory to capture screen.');
else
alert('Multi-capturing of screen is not allowed. Capturing process is denied. Are you enabled flag: "Enable screen capture support in getUserMedia"?');
} else
alert('Webcam access is denied.');
});
window.isAudio = false;
if (isRecordVideo) {
recordVideo.disabled = true;
stopRecordingVideo.disabled = false;
pauseResumeVideo.disabled = false;
}
}
stopRecordingVideo.onclick = function() {
this.disabled = true;
recordVideo.disabled = false;
if (recorder)
recorder.stopRecording(function(url) {
video.src = url;
video.play();
document.getElementById('video-url-preview').innerHTML = 'Recorded Video URL';
});
};
</script>
<script>
document.getElementById('fit-to-screen').onclick = function() {
this.disabled = true;
video.width = canvasWidth_input.value = innerWidth;
video.height = canvasHeight_input.value = innerHeight;
};
</script>
You will have to use the recorder.getBlob() method to get the actual blob of the video file, then send it to your server which will then save it to a file :
javascript:
stopRecordingVideo.onclick = function() {
this.disabled = true;
recordVideo.disabled = false;
if (recorder)
recorder.stopRecording(function(url) {
video.src = url;
video.play();
var recordedBlob = recorder.getBlob();
var formData = new FormData();
formData.append("videofile", recordedBlob);
var xhr = new XMLHttpRequest();
xhr.open("POST", "savevideofile.php");
xhr.send(formData);
document.getElementById('video-url-preview').innerHTML = '<a href="' + url + '>Recorded Video URL</a>';
});
};
savevideofile.php:
<?php
if($_FILES['videofile']){
$my_file = $_FILES['videofile'];
$my_blob = file_get_contents($my_file['tmp_name']);
file_put_contents('/path/to/your/file.webm', $my_blob);
}
?>
After looking at the source code of the web page you linked, the 'url' from your callback for stopRecording should be a downloadable URL.
All you'd have to do would be to take that URL and use it in an anchor with HTML5 download attribute, like so:
recorder.stopRecording(function(url) {
video.src = url;
video.play();
document.getElementById('video-url-preview').innerHTML = 'Recorded Video URL';
});

MediaStreamRecorder - Recording Audio Issue

I've just rummaged through and put together an audio-video recorder that will record audio and video streams separately and upload them to my server where they'll get joined.
BUT, my implementation has the audio dropping off after a few seconds mostly 7 seconds and 14 seconds.
I'm using RecordRTC javascript library and here's the link: https://www.webrtc-experiment.com/RecordRTC.js
And here's the code:
var record = document.getElementById('replyfallback_record');
var stop = document.getElementById('replyfallback_cancel');
var audio = document.querySelector('audio');
var recordVideo = document.getElementById('record-video');
var preview = document.getElementById('replyfallback_video');
var recordAudio, recordVideo, progress;
$('#replyfallback_record').click(function(){
switch($('#replyfallback_record').text()){
case "Record":
//setup some variables
var video_constraints = {
mandatory: { },
optional: []
};
//trigger navigator.getUserMedia
navigator.getUserMedia({
audio: true,
video: true
}, function(stream) {
preview.src = window.URL.createObjectURL(stream);
preview.play();
// var legalBufferValues = [256, 512, 1024, 2048, 4096, 8192, 16384];
// sample-rates in at least the range 22050 to 96000.
recordAudio = RecordRTC(stream, {
type: 'audio',
bufferSize: 16384,
sampleRate: 45000
});
/*recordVideo = RecordRTC(stream, {
type: 'video'
});*/
recordAudio.startRecording();
//recordVideo.startRecording();
$('#replyfallback_record').text("Stop & Submit");
});
break;
case "Stop & Submit":
$('#replyfallback_record').attr('disable','disable');
fileName = uid();
recordAudio.stopRecording(function(url){
window.open(url);
});
PostBlob(recordAudio.getBlob(), 'HTML5UploadAudio', fileName);
//recordVideo.stopRecording();
//PostBlob(recordVideo.getBlob(), 'HTML5UploadVideo', fileName);
preview.src = '';
$('#replyfallback_record').text("submitting...");
break;
}
});
//basic ajax request object function
function xhr(url, data, progress, callback) {
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
callback(request.responseText);
}
};
request.onprogress = function(e) {
if(!progress) return;
if (e.lengthComputable) {
progress = (e.loaded / e.total) * 100;
}
$('#replyfallback_record').text("submitting..."+progress);
if(progress == 100){
progress = 0;
}
};
request.open('POST', url);
request.send(data);
}
function PostBlob(blob, fileType, fileName) {
// FormData
var formData = new FormData();
formData.append('filename', fileName);
formData.append('blob', blob);
formData.append("function",fileType);
if(fileType=="HTML5UploadVideo"){
formData.append("CN_UL_title",$('#replyfallback_title').val());
formData.append("CN_UL_description",$('#replyfallback_desc').val());
formData.append("CN_UL_category","1");
}
// POST the Blob
xhr(SITE.api, formData, progress, function(data) {
$('#replyfallback_record').text("Record");
alert(data+" | "+getReadableFileSizeString(recordAudio.getBlob().size));
});
}
It is a little late reply, but may be help future visitor.
Please try PostBlob(recordAudio.getBlob(), 'HTML5UploadAudio', fileName); inside stopRecording callback function.
recordAudio.stopRecording(function(url){
PostBlob(recordAudio.getBlob(), 'HTML5UploadAudio', fileName);
window.open(url);
});

Fb graph api permissions aren't working

I am using facebook login and its graph api to list all images of user to my website and the following code is working fine only for me that is the administrator and owner of the facebook app, it is not working for anyother person when he logged in the website using facebook login.
Explanation of code: When user logged in, a function named testAPI is called which gets user basic information and then it makes another call to FB.API for permission access and then finally for getting pictures.
The permission parameter "res" gets nothing for anyother user, but its working for me(administrator).
heres the code:
<div id="fb-root"></div>
<script>
// Additional JS functions here
window.fbAsyncInit = function() {
FB.init({
appId : MY_APP_ID, // App ID
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
testAPI();
} else if (response.status === 'not_authorized') {
login();
} else {
login();
}
});
};
function login() {
FB.login(function(response) {
if (response.authResponse) {
testAPI();
} else {
// cancelled
}
},{scope:'user_photos',perms:'user_photos'});
}
var id;
function testAPI() {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Good to see you, ' + response.name + '.');
console.log(response);
id=response.id;
var link='/'+ id + '/permissions?access_token=FB_GENERATED_ACCESS_TOKEN';
FB.api(link,function(res){
console.log("permissons: ",res);
link='/'+ id + '/photos?fields=images';
FB.api(link, function(response) {
//placing all pictures
for(var i=0;i<response.data.length;i++)
{
var img="<img src="+response.data[i].images[0].source+" class='small' />";
$("#images").append(img);
}
console.log(response);
});
});
});}
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
</script></body>
<fb:login-button autologoutlink='true'
perms='email,user_birthday,status_update,publish_stream'></fb:login-button>
<div id="images"></div>
I got your actual problem,
<fb:login-button autologoutlink='true'
perms='email,user_birthday,status_update,publish_stream'></fb:login-button>
You missing out here , user_photos permission. your javascript function is not calling because fb:login-button do all stuff by self. your new code should be :
<fb:login-button autologoutlink='true'
perms='email,user_birthday,status_update,publish_stream,user_photos'></fb:login-button>
Instead of
var link='/'+ id + '/permissions?access_token=FB_GENERATED_ACCESS_TOKEN';
FB.api(link,function(res){
console.log("permissons: ",res);
link='/'+ id + '/photos?fields=images';
FB.api(link, function(response) {
//placing all pictures
for(var i=0;i<response.data.length;i++)
{
var img="<img src="+response.data[i].images[0].source+" class='small' />";
$("#images").append(img);
}
console.log(response);
});
Try this:
FB.api('/me/permissions', function (response) {
console.log("permissons: ", res);
var perms = response.data[0];
if (perms.user_photos) {
FB.api('/me/photos?fields=images', function (response) {
//placing all pictures
for (var i = 0; i < response.data.length; i++) {
var img = "<img src=" + response.data[i].images[0].source + " class='small' />";
$("#images").append(img);
}
console.log(response);
} else {
// User DOESN'T have permission. Perhaps ask for them again with FB.login?
login();
}
});