Camera Plugin not opening camera in Ionic 4 - javascript

I am working on a project in Ionic 4.
I would like user to upload picture by capturing from camera or uploading from library. For now I am running in development mode. The problem is that I am not being able to open camera or photo library on device in debugging mode. However the camera is opening when I run on "DEVAPP". I have tried taking permission but nothing is working out. Here is my code, tried many ways therefore code is a bit scattered:
async selectImage() {
try {
const actionSheet = await this.actionSheetController.create({
header: 'Select Image source',
buttons: [{
text: 'Load from Library',
handler: () => {
this.takePicture(this.camera.PictureSourceType.PHOTOLIBRARY);
}
},
{
text: 'Use Camera',
handler: () => {
this.takePicture(this.camera.PictureSourceType.CAMERA);
}
},
{
text: 'Cancel',
role: 'cancel'
}
]
});
await actionSheet.present();
} catch (error) {
alert(error);
}
}
takePicture(sourceType: PictureSourceType) {
const options: CameraOptions = {
quality: 100,
sourceType,
saveToPhotoAlbum: false,
correctOrientation: true
};
alert('i m n takepicture');
this.androidPermissions.requestPermissions([this.androidPermissions.PERMISSION.CAMERA]).then(
result => console.log('i am asking for permision: ' + result),
err => this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.CAMERA)
);
if (this.camera.PictureSourceType.CAMERA) {
this.androidPermissions.checkPermission(this.androidPermissions.PERMISSION.CAMERA).then(
result =>
this.camera.getPicture(options).then(imagePath => {
if (this.plt.is('android') && sourceType === this.camera.PictureSourceType.PHOTOLIBRARY) {
this.filePath.resolveNativePath(imagePath)
.then(filePath => {
const correctPath = filePath.substr(0, filePath.lastIndexOf('/') + 1);
const currentName = imagePath.substring(imagePath.lastIndexOf('/') + 1, imagePath.lastIndexOf('?'));
this.copyFileToLocalDir(correctPath, currentName, this.createFileName());
}). catch((error) => {
console.warn('error: ' + error);
});
} else {
const currentName = imagePath.substr(imagePath.lastIndexOf('/') + 1);
const correctPath = imagePath.substr(0, imagePath.lastIndexOf('/') + 1);
this.copyFileToLocalDir(correctPath, currentName, this.createFileName());
}
}),
err => this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.CAMERA));
} else {
this.androidPermissions.checkPermission(this.androidPermissions.PERMISSION.PHOTOLIBRARY).then(
result =>
this.camera.getPicture(options).then(imagePath => {
if (this.plt.is('android') && sourceType === this.camera.PictureSourceType.PHOTOLIBRARY) {
this.filePath.resolveNativePath(imagePath)
.then(filePath => {
const correctPath = filePath.substr(0, filePath.lastIndexOf('/') + 1);
const currentName = imagePath.substring(imagePath.lastIndexOf('/') + 1, imagePath.lastIndexOf('?'));
this.copyFileToLocalDir(correctPath, currentName, this.createFileName());
});
} else {
const currentName = imagePath.substr(imagePath.lastIndexOf('/') + 1);
const correctPath = imagePath.substr(0, imagePath.lastIndexOf('/') + 1);
this.copyFileToLocalDir(correctPath, currentName, this.createFileName());
}
}),
err => this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.PHOTOLIBRARY));
}
}

Try this
takePicture(sourceType: PictureSourceType) {
const options: CameraOptions = {
quality: 100,
sourceType:sourceType,
saveToPhotoAlbum: false,
correctOrientation: true
};
this.camera.getPicture(options).then(
imageData => {
///DO YOUR LOGIC
},
err => {
// Handle error
}
);
}

Related

ERR_STREAM_PUSH_AFTER_EOF error in ffmpeg

I got this error ( ERR_STREAM_PUSH_AFTER_EDF ) a lot when i stay in voice channel for a long time, this error only happen when i stay in the voice channel for like minute or more, when i stay in voice channel for couple of seconds the code return no errors, and this my ffmpeg part of code :
try {
let proc = new ffmpeg(`./abdlmutiiRecords/r-${myID}.pcm`);
proc.then(function(audio) {
audio.fnExtractSoundToMP3('./abdlmutiiRecords/mp3-' + myID + ".mp3", function(error, file) {
if (!error) {
ab.guild.channels.cache.get("983142179734175814").send({
embeds: [abdlmutiiEmbedLog],
files: [new dis.MessageAttachment('./abdlmutiiRecords/mp3-' + myID + ".mp3", "record.mp3")]
});
}
});
}, function(err) {
console.log('Error: ' + err);
});
} catch (e) {
console.log(e);
}
Also this my full code :
bot.on("interactionCreate", async ab => {
if (ab.isButton()) {
let myID = abdlmutiiID("10");
if (ab.customId === "recordButton") {
await ab.deferReply();
let startEmbed = new dis.MessageEmbed().setDescription("**جاري تسجيل المكالمة، ان انتهيت الرجاء الضغط على زر الإيقاف بالاسفل، يرجى معرفة ان التسجيل سيكون مدته ٣٠ دقيقة ان لم يتم الضغط على زر الإيقاف**").setColor("GREEN");
let startRow = new dis.MessageActionRow().addComponents(new dis.MessageButton().setLabel("الأيقاف").setStyle("DANGER").setCustomId(`stopButton${myID}`), ) let voiceChannel = ab.member.voice.channel;
if (!voiceChannel) return ab.reply("Please join a voice channel first!");
await ab.editReply({
embeds: [startEmbed],
components: [startRow],
ephemeral: true
});
const connection = await bot.voiceManager.join(voiceChannel, {
selfMute: true
});
const receiver = connection.receiver.createStream(ab.member, {
mode: "pcm",
end: "silence"
});
const writer = await receiver.pipe(fs.createWriteStream(`./abdlmutiiRecords/r-${myID}.pcm`));
const collector = ab.channel.createMessageComponentCollector({
componentType: 'BUTTON'
});
collector.on('collect', i => {
if (i.user.id === ab.user.id && i.customId === `stopButton${myID}`) {
connection.destroy();
let abdlmutiiEmbedLog = new dis.MessageEmbed().setAuthor(ab.user.tag, ab.user.avatarURL({
dynamic: true
})).setDescription(`**أيدي التسجيل**: ${myID}\n**القناة الصوتية**: ${ab.member.voice.channel.name}\n**منذ**: `);
const ffmpeg = require('ffmpeg');
try {
let proc = new ffmpeg(`./abdlmutiiRecords/r-${myID}.pcm`);
proc.then(function(audio) {
audio.fnExtractSoundToMP3('./abdlmutiiRecords/mp3-' + myID + ".mp3", function(error, file) {
if (!error) {
ab.guild.channels.cache.get("983142179734175814").send({
embeds: [abdlmutiiEmbedLog],
files: [new dis.MessageAttachment('./abdlmutiiRecords/mp3-' + myID + ".mp3", "record.mp3")]
});
}
});
}, function(err) {
console.log('Error: ' + err);
});
} catch (e) {
console.log(e);
}
}
});
}
}
})

I can't figure out what is preventing line wrapping

I have a script when using the library typed.js . I'm trying to output 3 lines + 1 final one. The code works by outputting 2 lines + 1 final one. When trying to fix it, the code freezes without sending an error.
This version of the code works without errors. Outputs 2 lines + 1.
const lineNumber = app.id !== 2 ? ++app.id : (app.id += 2);
setTimeout(() => {
const typed = new Typed(`#line${lineNumber}`, {
strings: text,
typeSpeed: speed,
onComplete: callback,
});
}, timeout);
};
$.getJSON(ipgeolocation, (data) => {
writeLine(["line1"], 30, () => {
if (app.skippedIntro) return;
clearCursor();
const usernames = ['user', 'dude'];
const ip = data.ip ? data.ip : usernames[Math.floor(Math.random() * usernames.length)];
const country = data.country_name ? data.country_name : 'your country';
writeLine([`line2`], 30, 500, () => {
if (app.skippedIntro) return;
clearCursor();
writeLine([`start`], 120, 500, () => {
timeouts.push(
setTimeout(() => {
if (app.skippedIntro) return;
clearCursor();
setTimeout(() => {
skipIntro();
}, 500);
}, 1000)
);
});
});
});
});
This version of the code does not work. According to the idea, it should output 3 lines + 1.
1.
const lineNumber = app.id !== 2 ? ++app.id : (app.id += 2);
setTimeout(() => {
const typed = new Typed(`#line${lineNumber}`, {
strings: text,
typeSpeed: speed,
onComplete: callback,
});
}, timeout);
};
$.getJSON(ipgeolocation, (data) => {
writeLine(["line1"], 30, () => {
if (app.skippedIntro) return;
clearCursor();
const usernames = ['user', 'dude'];
const ip = data.ip ? data.ip : usernames[Math.floor(Math.random() * usernames.length)];
const country = data.country_name ? data.country_name : 'your country';
writeLine([`line2`], 30, 500, () => {
if (app.skippedIntro) return;
clearCursor();
writeLine([`line3`], 30, 500, () => {
if (app.skippedIntro) return;
clearCursor();
writeLine([`start`], 120, 500, () => {
timeouts.push(
setTimeout(() => {
if (app.skippedIntro) return;
clearCursor();
setTimeout(() => {
skipIntro();
}, 500);
}, 1000)
);
});
});
});
});
});
We have the main bands and when you get 3, you need to add 2 to learn the 5th.
const lineNumber = app.id !== 3 ? ++app.id : (app.id += 2);

How to pass a stream from page to page while the user navigates? Chrome extension Manifest V3

I'm developing a manifest v3 Google Chrome extension that aims to take screenshots and record user browsing.
Problem: When I navigate from one page to another while screen sharing the stream is lost.
Question 1: how to pass the stream between navigation pages?
Question 2: how to store the stream so that when loading the next page the stream is maintained?
Note:
In the service worker I use chrome.desktopCapture.chooseDesktopMedia to bring up the screen sharing window, with this I get the stream id which is then sent to the content script found on the page, where I use navigator.mediaDevices.getUserMedia to get the stream which I then place inside a video element. This video object allows me to take screenshots with canvas.
Viewing some extensions with manifest v2 use the background pages to store the video object and the scripts that create the stream. But now with the service worker in manifest v3, how could I do it?
My code:
Service worker:
chrome.runtime.onConnect.addListener(function (port) {
port.onMessage.addListener(function (msg) {
if (msg.type === 'SS_UI_REQUEST') {
requestScreenSharing(port, msg)
}
if (msg.type === 'SS_UI_TAKESCREENSHOT') {
console.log(msg.top);
StartCountDown(port, msg);
}
});
});
// const sources = ['screen', 'window', 'tab', 'audio'];
async function requestScreenSharing(port, msg) {
const sources = ['screen'];
const tab = port.sender.tab;
chrome.desktopCapture.chooseDesktopMedia(
sources,
port.sender.tab,
streamId => {
if (streamId) {
msg.type = 'SS_DIALOG_SUCCESS';
msg.streamId = streamId;
msg.text = "sharing";
} else {
msg.type = 'SS_DIALOG_CANCEL';
msg.text = "cancel";
}
var tab = getTabId();
tab.then((value) => {
const respuesta = chrome.tabs.connect(value.id, {
name: "respuesta",
});
respuesta.postMessage(msg);
});
}
);
}
let seconds = 3;
let id;
async function StartCountDown(port, msg) {
const css1 = 'body::after{ display: flex; height: 100vh;justify-content: center;align-items: center; background:rgb(76,76,76); opacity: 0.7; content: "Capturando pantalla.. 3"; color:white;font-size: 50px;font-weight: 500; width:100%; position: absolute;top:'+msg.top+'px;left: 0; z-index: 2040;}'
const css2 = 'body::after{ content: "Capturando pantalla.. 2";}'
const css3 = 'body::after{ content: "Capturando pantalla.. 1";}'
myIntervalId = setInterval(function () {
IntervalId = myIntervalId;
if (seconds > 0) {
chrome.action.setBadgeBackgroundColor({
color: [255, 0, 0, 255]
});
chrome.action.setBadgeText({
text: seconds.toString()
});
if (seconds == 3) {
var csstab = getTabId();
csstab.then((value) => {
chrome.scripting.insertCSS({
target: {
tabId: value.id
},
css: css1,
});
});
}
if (seconds == 2) {
var csstab = getTabId();
csstab.then((value) => {
chrome.scripting.insertCSS({
target: {
tabId: value.id
},
css: css2,
});
});
}
if (seconds == 1) {
var csstab = getTabId();
csstab.then((value) => {
chrome.scripting.insertCSS({
target: {
tabId: value.id
},
css: css3,
});
});
}
seconds--;
} else {
chrome.action.setBadgeText({
'text': ''
});
seconds = 3;
clearInterval(IntervalId);
msg.type = 'SS_UI_TAKESCREENSHOT_SUCCESS';
msg.text = "takingScreenShot";
var tab = getTabId();
tab.then((value) => {
chrome.scripting.removeCSS({
target: {
tabId: value.id
},
css: css1,
});
chrome.scripting.removeCSS({
target: {
tabId: value.id
},
css: css2,
});
chrome.scripting.removeCSS({
target: {
tabId: value.id
},
css: css3,
});
const respuesta = chrome.tabs.connect(value.id, {
name: "respuesta",
});
respuesta.postMessage(msg);
});
}
}, 1000);
}
async function getTabId() {
let queryOptions = {
active: true,
currentWindow: true
};
let [tab] = await chrome.tabs.query(queryOptions);
return tab;
}
content-script
chrome.runtime.onConnect.addListener(function (port) {
port.onMessage.addListener(function(msg){
if (msg.type === 'SS_UI_REQUEST') {
console.log(msg);
if(!window.stream)
{
var messenger = chrome.runtime.connect();
messenger.postMessage(msg);
}else
{
console.log(msg);
var messenger = chrome.runtime.connect();
messenger.postMessage({ type: 'SS_UI_TAKESCREENSHOT', top: window.scrollY.toString() },'*');
}
}
if (msg.type === 'SS_DIALOG_SUCCESS') {
startScreenStreamFrom(msg.streamId);
console.log(msg);
var messenger = chrome.runtime.connect();
messenger.postMessage({ type: 'SS_UI_TAKESCREENSHOT', top: window.scrollY.toString() },'*');
}
if (msg.type === 'SS_UI_CHANGE_CSS') {
console.log(msg);
}
if (msg.type === 'SS_DIALOG_CANCEL') {
console.log(msg);
}
if(msg.type === "SS_UI_TAKESCREENSHOT_SUCCESS")
{
console.log(msg);
setTimeout(function() {
TakeScreenShot();
}, 300);
}
if(msg.type === "SS_UI_RECORDSCREEN")
{
console.log("Grabar pantalla");
RecordScreen();
}
});
});
function startScreenStreamFrom(streamId) {
console.log("compartiendo pantalla");
navigator.mediaDevices
.getUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: streamId
}
}
})
.then(stream => {
var video = document.getElementById("ElementNotExist");
if(video)
{
video.remove();
}
window.stream = stream;
window.stream.getVideoTracks()[0].onended = function () {
window.stream = null;
};
var video = document.createElement('video');
video.srcObject = stream;
video.type = 'video/ogg';
video.autoplay = true;
video.setAttribute("id","ElementNotExist");
video.style.display = "none";
document.body.appendChild(video);
});
}
Index.js Extension script.
document.getElementById("btn-capture").addEventListener("click", function () {
var tab = getTabId();
tab.then((value) => {
chrome.storage.local.set({ 'pestaña': value.id });
const port = chrome.tabs.connect(value.id, {
name: "conexion",
});
port.postMessage({ type: 'SS_UI_REQUEST', text: 'start' }, '*');
window.close();
chrome.action.setPopup({popup: "capture.html"});
});
})
async function getTabId() {
let queryOptions = { active: true, currentWindow: true };
let [tab] = await chrome.tabs.query(queryOptions);
return tab;
}

[react native][ios][react-native-background-fetch] dont't work on ios

I've implemented react-native-background-fetch in my app, and it works well on Android, but not on ios - Xcode Version 11.4
Simulate Background Fetch works. I noticed also that Background Fetch triggers once on the first application start, but not anymore. On Android Background Fetch triggers every 15 min.
My configuration is:
react-native: 0.62.1
react-native-background-fetch: 2.8.0
Here is my code:
App.js
class App extends Component {
componentDidMount () {
...
newPostNotificationService.initNotifications()
...
newPostsNotificationSevice.js
initNotifications = async () => {
this.configureNotifications() // Configures PushNotification
BackgroundFetch.registerHeadlessTask(this.fetchNewPosts)
BackgroundFetch.configure({
minimumFetchInterval: 15,
stopOnTerminate: false,
startOnBoot: true,
enableHeadless: true
}, this.fetchNewPosts,
(error) => {
console.log(error, '[js] RNBackgroundFetch failed to start')
})
BackgroundFetch.status((status) => {
switch (status) {
case BackgroundFetch.STATUS_RESTRICTED:
console.log('BackgroundFetch restricted')
break
case BackgroundFetch.STATUS_DENIED:
console.log('BackgroundFetch denied')
break
case BackgroundFetch.STATUS_AVAILABLE:
console.log('BackgroundFetch is enabled')
break
}
})
}
fetchNewPosts Method in newPostsNotificationSevice.js
async fetchNewPosts(taskId) {
console.log('BackgroundFetch Start', taskId)
if (AppState.currentState === 'active') {
BackgroundFetch.finish(taskId)
return
}
dataStorageService.getSettings().then(async (settings) => {
if (!settings.notifications) {
BackgroundFetch.finish(taskId)
return
}
const url = config.API_URL + config.API_ENDPOINTS.POSTS + '&per_page=1&page=1'
let data
if (!config.DATA_MOCK.NEW_POSTS) {
data = await fetch(url)
.then((response) => {
return response.json()
})
.catch((error) => {
console.error(error)
})
} else {
data = postsMock.posts
}
data = data.map(item => {
return new PostShort(item)
})
data = data.filter(item => {
return item.sendPush
})
if (data.length === 0) {
BackgroundFetch.finish(taskId)
}
dataStorageService.getPostsIndex().then(postsIndex => {
if (postsIndex.length > 0 && postsIndex.indexOf(data[0].id) !== -1) {
BackgroundFetch.finish(taskId)
return
}
dataStorageService.getNotificationsIndex().then(notificationsIndex => {
if (notificationsIndex.indexOf(data[0].id) !== -1) {
BackgroundFetch.finish(taskId)
return
}
const notificationBody = entities.decode(data[0].title)
const notificationNumber = notificationsIndex.length + 1
console.log('notificationNumber', notificationNumber)
PushNotification.localNotification({
title: config.NOTIFICATION_TITLE, // (optional)
message: notificationBody, // (required)
playSound: true, // (optional) default: true
soundName: 'default',
number: notificationNumber,
id: notificationNumber.toString()
})
dataStorageService.insertIntoNotificationsIndex([data[0].id])
BackgroundFetch.finish(taskId)
})
})
})
}
I made iOS setup following this instructions: https://github.com/transistorsoft/react-native-background-fetch/blob/HEAD/docs/INSTALL-AUTO-IOS.md
Why Background Fetch doesn't trigger periodically on iOS like on Android does?

Can't Google auth with multiple accounts

I am trying to use the google apis with multiple users in my chrome extension.
The main problems are:
1) If I'm not logged in into browser I can't auth with google
2) If I login in browser and then try to log in to the app, then autorisoes under that account and in chrome, no matter what account I chose in the menu.
Function toggleGetIdTokenListener invoked from the background.
export const toggleGetIdTokenListener = () => {
chrome.runtime.onMessage.addListener((request) => {
if (request.type === 'get_idToken') {
getTokenId();
}
});
};
const createRequestURL = () => {
const manifest = chrome.runtime.getManifest();
const clientId = encodeURIComponent(manifest.oauth2.client_id);
const scopes = encodeURIComponent(manifest.oauth2.scopes.join(' '));
const redirectUri = encodeURIComponent('urn:ietf:wg:oauth:2.0:oob:auto');
const url = 'https://accounts.google.com/o/oauth2/auth' +
'?client_id=' + clientId +
'&response_type=id_token' +
'&access_type=offline' +
'&redirect_uri=' + redirectUri +
'&scope=' + scopes;
return url;
};
const getTokenId = () => {
chrome.tabs.create({
url: createRequestURL(),
active: false
}, getResponseFromGoogle);
};
const getResponseFromGoogle = (authenticationTab) => {
const RESULT_PREFIX = ['Success', 'Denied', 'Error'];
// After the tab has been created, open a window to inject the tab
chrome.tabs.onUpdated.addListener(function googleAuthorizationHook(tabId, changeInfo) {
const titleParts = changeInfo.title.split(' ', 2);
const result = titleParts[0];
if (titleParts.length === 2 && RESULT_PREFIX.indexOf(result) >= 0) {
chrome.tabs.onUpdated.removeListener(googleAuthorizationHook);
chrome.tabs.remove(tabId);
const response = titleParts[1];
chrome.identity.getAuthToken({'interactive': true}, function (token) {
if (chrome.runtime.lastError) {
console.log('ERROR', chrome.runtime.lastError.message);
return;
}
const x = new XMLHttpRequest();
x.open('GET', 'https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=' + token);
x.onload = function () {
populateUserData(JSON.parse(x.response), response);
};
x.send();
});
}
});
createPopupWindow(authenticationTab)
};
const createPopupWindow = (authenticationTab) => {
chrome.windows.create({
tabId: authenticationTab.id,
type: 'popup',
focused: true
// incognito, top, left, ...
}, function () {
chrome.tabs.update(authenticationTab.id, {'url': createRequestURL()});
});
};
const populateUserData = (userInfo, id_token) => {
const userData = [{
name: userInfo.name,
email: userInfo.email,
id_token: id_token.substring(id_token.indexOf('=') + 1, id_token.indexOf('&')),
clientId: '711602808537-cv3p6pe7hc2lvmo88ri0oti0rcqcme7a.apps.googleusercontent.com',
picture: userInfo.picture
}];
connector.init();
getUserFromServer(userData);
};
Any ideas? Thanks anyway!

Categories