Getting Only one Screen while recording Agora - agora.io

I m getting only one screen while recording the screen
My Config
Start Recording
https://api.agora.io/v1/apps/${config.agora.appID}/cloud_recording/resourceid/${resource}/mode/${mode}/start,
{
cname: ',
uid: String(uid),
clientRequest: {
token,
recordingConfig: {
// subscribeVideoUids: ['#allstream#'],
// subscribeAudioUids: ['#allstream#'],
subscribeUidGroup: 0,
maxIdleTime: 30,
streamTypes: 2,
channelType: 0,
videoStreamType: 0,
audioProfile: 1,
transcodingConfig: {
height: 640,
width: 480,
bitrate: 400,
fps: 15,
mixedVideoLayout: 1,
backgroundColor: '#FFFFFF'
}
},
recordingFileConfig: {
avFileType: ['hls', 'mp4']
},
storageConfig: {
vendor: 1,
region: 14,
bucket: '',
accessKey: '',
secretKey: '*****',
fileNamePrefix: ['media', 'recordings']
}
}
},
{ headers: { Authorization } }
Stop Recording
`http://api.agora.io/v1/apps/${config.agora.appID}/cloud_recording/resourceid/${resource}/sid/${sid}/mode/${mode}/stop`, {
cname: eventId,
uid: String(uid),
clientRequest: {
async_stop: false
}
},
{ headers: { Authorization } }

You should use "mix" as the value for your mode if you wish to have all the screens in the recording. If you are using "individual" as mode you will get multiple dumps for each users audio and video.

Related

How can I call a method from options of ApexChart with vue.js

I'm new with vue and apex charts, basically what I need is to call a method from the apex chart options, I created a file showing the problem I'm having:
https://jsfiddle.net/wr3uo5va/
I need to call the method currencyValue from chartOptions.dataLabels
dataLabels: {
enabled: true,
offsetX: -25,
formatter: function(val) {
return val + " Reais"; <--- This works
// return this.currencyValue(val) <--- This does not work
},
},
Any suggestion ?
The problem is this inside the formatter callback is the chart instance (not the component instance) because it's declared as a regular function.
The solution is to use an arrow function to bind the component instance as the context:
export default {
methods: {
currencyValue(value) {⋯},
loadChartData() {
⋮
this.chartOptions = {
⋮
dataLabels: {
⋮
// ❌ don't use regular function here
//formatter: function(val) {
// return this.currencyValue(val)
//},
// ✅
formatter: (val) => {
return this.currencyValue(val)
},
},
}
}
}
}
updated fiddle
You can put chartOptions in methods instead of in data.
Below is working code
const currencyValue = (val) => {
return "R$" + val;
}
new Vue({
el: "#app",
data() {
return {
series: [450, 300, 500]
}
},
methods: {
chartOptions() {
return {
labels: ['Paid', 'Pending', 'Rejected'],
plotOptions: {
radialBar: {
size: 165,
offsetY: 30,
hollow: {
size: '20%'
},
track: {
background: "#ebebeb",
strokeWidth: '100%',
margin: 15,
},
dataLabels: {
show: true,
name: {
fontSize: '18px',
},
value: {
fontSize: '16px',
color: "#636a71",
offsetY: 11
},
total: {
show: true,
label: 'Total',
formatter: function() {
return 42459
}
}
}
},
},
responsive: [{
breakpoint: 576,
options: {
plotOptions: {
radialBar: {
size: 150,
hollow: {
size: '20%'
},
track: {
background: "#ebebeb",
strokeWidth: '100%',
margin: 15,
},
}
}
}
}],
colors: ['#7961F9', '#FF9F43', '#EA5455'],
fill: {
type: 'gradient',
gradient: {
// enabled: true,
shade: 'dark',
type: 'vertical',
shadeIntensity: 0.5,
gradientToColors: ['#9c8cfc', '#FFC085', '#f29292'],
inverseColors: false,
opacityFrom: 1,
opacityTo: 1,
stops: [0, 100]
},
},
stroke: {
lineCap: 'round'
},
chart: {
dropShadow: {
enabled: true,
blur: 3,
left: 1,
top: 1,
opacity: 0.1
},
},
tooltip: {
x: {
formatter: function (val) {
return val;
},
},
y: {
formatter: function (val) {
return currencyValue(val);
},
},
},
}
}
},
components: {
VueApexCharts
}
})
Methods can't be called in data or computed, they can be called in methods
One thing to be modified in html is below
<vue-apex-charts
type="donut"
:options="chartOptions()"
:series="series">
</vue-apex-charts>

Highchart gauge not displaying min/max value in Vue.js

I have a weird issue. I am displaying data from a neo4j database onto the highcharts. I am able to retrieve the data, but when i try to put it onto the charts, some of it doesnt display. Here is my gauge code
CustomGauge.vue
<template>
<highcharts :options="chartOptions"></highcharts>
</template>
<script>
import { Chart } from "highcharts-vue";
export default {
name: "CustomGuage",
components: {
highcharts: Chart
},
props: ["data", "title", "range1", "range2", "min", "max"],
data() {
return {
chartOptions: {
chart: {
type: "gauge",
// plotBackgroundColor: null,
// plotBackgroundImage: null,
// plotBorderWidth: 0,
// plotShadow: false,
//marginBottom: 170,
},
credits: {
enabled: false
},
title: {
text: this.title,
align: "left"
},
pane: {
startAngle: -150,
endAngle: 150,
size: 200,
background: {
borderWidth: 0
}
},
// the value axis
yAxis: {
min: this.min,
max: this.max,
// tickPixelInterval: 30,
// tickWidth: 2,
// tickColor: "#666",
plotBands: [
{
from: 0,
to: this.range1,
color: "#55BF3B" // green
},
{
from: this.range1,
to: this.range2,
color: "#DDDF0D" // yellow
},
{
from: this.range2,
to: 1000,
color: "#DF5353" // red
}
]
},
series: [
{
data: this.data
// tooltip: {
// valueSuffix: " km/h"
// }
},
// // {
// // data: this.target,
// // dataLabels: {
// // enabled: true,
// // format: "Target: {y}%",
// // verticalAlign: "bottom",
// // borderWidth: 0
// // //useHTML: true,
// // },
// }
]
}
};
},
watch: {
data(newVal) {
this.chartOptions.series[0].data = newVal;
}
}
};
I define my chart like this
<CustomGuage :title="gaugeTitle1" :data="gaugeData1" :min="gauge1min" :max="gauge1max" :range1="gauge1Range1" :range2="gauge1Range2" />
I initialize it in data() like this -
gaugeTitle1: [],
gaugeData1: [],
gauge1Range1: [],
gauge1Range2: [],
gauge1min: [],
gauge1max: [],
Using the neo4j-vuejs connector, i retrieve the data like this -
const session19 = this.$neo4j.getSession();
// KPI 1
session19
.run(
"match (n:proj) where exists(n.min) return n.name as title,n.min as min,n.max as max,n.range1
as range1,n.range2 as range2,n.target AS target, n.current as data"
)
.then((res) => {
// KPI 1-------------------------
this.data1 = res.records[0].get("data");
var a = JSON.parse(this.data1);
this.gaugeData1.push(a);
console.log(a)
this.min1 = res.records[0].get("min");
var b = JSON.parse(this.min1);
this.gauge1min = b;
console.log(this.gauge1min)
this.max1 = res.records[0].get("max");
var c = JSON.parse(this.max1);
this.gauge1max = c;
console.log(this.gauge1max)
this.title1 = res.records[0].get("title");
this.gaugeTitle1.push(this.title1)
console.log(this.gaugeTitle1);
})
.then(() => {
session.close();
});
The retrieval of data works fine, i checked in the console.The weird part is if i comment/uncomment or change something in CustomGauge.vue, the charts displays perfectly, displays everything perfectly from the database.But once i refresh the page, it is gone. Could someone help me out. thanks for your help in advance
Probably a reactivity issue.
Instead of
this.chartOptions.series[0].data = newVal;
Try
this.$set(this.chartOptions.series[0], 'data', newVal)

VueJS + Chartjs - Chart only renders after code change

I'm using the following tutorial (pull download stats for NPM packages) to build a basis for my charted webapp :
https://hackernoon.com/lets-build-a-web-app-with-vue-chart-js-and-an-api-544eb81c4b44
https://github.com/apertureless/npm-stats
I have extracted the below code from the tutorial and modified it so it does the pure basics. Get data and present data. Specifically from these:
https://github.com/apertureless/npm-stats/blob/develop/src/pages/Start.vue
https://github.com/apertureless/npm-stats/blob/develop/src/components/LineChart.vue
Please note: The code executes the API call and retrieves data no problem. However it will only render that data in the chart if I make a code change. For example changing the color of a line to something else. It seems to only work on the next 'cycle' if that makes sense. Once the data has rendered, if I refresh that page it is once again blank. I suspect it has something to do with the pages timing. However not sure where to begin or what I'm looking for.
App.Vue
<template>
<v-app style="background-color: rgb(228, 228, 228);">
<section class="One">
<v-card class="One" color="rgb(255, 255, 255)" >
<LineChart :chart-data="downloads" :chart-labels="labels"/>
</v-card>
</section>
</v-app>
</template>
<script>
import axios from 'axios';
import LineChart from './components/test3.vue';
export default {
name: 'App',
components: {
LineChart,
},
data () {
return {
package: '',
packageName: '',
loaded: false,
loading: false,
downloads: [],
downloadsYear: [],
downloadsMonth: [],
downloadsWeek: [],
labels: [],
labelsYear: [],
labelsMonth: [],
labelsWeek: [],
showError: false,
showSettings: false,
errorMessage: 'Please enter a package name',
periodStart: '',
periodEnd: new Date(),
rawData: '',
totalDownloads: '',
dailyPng: null,
weeklyPng: null,
monthlyPng: null,
yearlyPng: null
}
},
mounted(){
this.loaded = false
axios.get(`https://api.npmjs.org/downloads/range/2017-01-01:2017-04-19/vue`)
.then(response => {
this.rawData = response.data.downloads
this.downloads = response.data.downloads.map(entry => entry.downloads)
this.labels = response.data.downloads.map(entry => entry.day)
this.packageName = response.data.package
this.totalDownloads = this.downloads.reduce((total, download) => total + download)
this.setURL()
this.groupDataByDate()
this.loaded = true
this.loading = false
})
.catch(err => {
this.errorMessage = err.response.data.error
this.loading = false
})
},
};
</script>
Chart Component:
<script>
import { Line } from 'vue-chartjs'
export default {
extends: Line,
props: {
chartData: {
type: Array,
required: false
},
chartLabels: {
type: Array,
required: true
}
},
data () {
return {
gradient: null,
options: {
showScale: true,
scales: {
yAxes: [{
ticks: {
beginAtZero: false,
},
gridLines: {
display: true,
color: '#EEF0F4',
borderDash: [5, 15]
}
}],
xAxes: [ {
gridLines: {
display: true,
color: '#EEF0F4',
borderDash: [5, 15]
}
}]
},
tooltips: {
backgroundColor: '#4F5565',
titleFontStyle: 'normal',
titleFontSize: 18,
bodyFontFamily: "'Proxima Nova', sans-serif",
cornerRadius: 3,
bodyFontColor: '#20C4C8',
bodyFontSize: 14,
xPadding: 14,
yPadding: 14,
displayColors: false,
mode: 'index',
intersect: false,
callbacks: {
title: tooltipItem => {
return `🗓 ${tooltipItem[0].xLabel}`
},
label: (tooltipItem, data) => {
let dataset = data.datasets[tooltipItem.datasetIndex]
let currentValue = dataset.data[tooltipItem.index]
return `📦 ${currentValue.toLocaleString()}`
}
}
},
legend: {
display: false
},
responsive: true,
maintainAspectRatio: false
}
}
},
mounted () {
this.gradient = this.$refs.canvas
.getContext('2d')
.createLinearGradient(0, 0, 0, 450)
this.gradient.addColorStop(0, 'rgba(52, 217, 221, 0.6)')
this.gradient.addColorStop(0.5, 'rgba(52, 217, 221, 0.25)')
this.gradient.addColorStop(1, 'rgba(52, 217, 221, 0)')
this.renderChart({
labels: this.chartLabels,
datasets: [
{
label: 'downloads',
borderColor: '#249EBF',
pointBackgroundColor: 'rgba(0,0,0,0)',
pointBorderColor: 'rgba(0,0,0,0)',
pointHoverBorderColor: '#249EBF',
pointHoverBackgroundColor: '#fff',
pointHoverRadius: 4,
pointHitRadius: 10,
pointHoverBorderWidth: 1,
borderWidth: 1,
backgroundColor: this.gradient,
data: this.chartData
}
]
}, this.options)
setTimeout(() => {
this.download()
}, 500)
},
methods: {
formatNumber (num) {
let numString = Math.round(num).toString()
let numberFormatMapping = [[6, 'm'], [3, 'k']]
for (let [numberOfDigits, replacement] of numberFormatMapping) {
if (numString.length > numberOfDigits) {
let decimal = ''
if (numString[numString.length - numberOfDigits] !== '0') {
decimal = '.' + numString[numString.length - numberOfDigits]
}
numString = numString.substr(0, numString.length - numberOfDigits) + decimal + replacement
break
}
}
return numString
}
}
}
</script>
You need to notify the child component to re-render itself.
add a watcher is one way, watch the data change and update it.
Another easier way is, add a key prop to it.
in your App.vue, do like this:
<LineChart :chart-data="downloads" :chart-labels="labels" :key="downloads.length"/>
here i'm using the downloads's length as key value. it's a simple and temp resolution to show you how to use key. In your app you should use some other value as key, incase different api call returns same length data.
you can also set the key to another value, and change this value every time you call the api.

Can't figure out how to send commands to bluetooth device

So i've been struggling to implement a bluetooth fingerprint reader that I got from aliexpress. I have looked for 2 days now on how to do it and I am at the stage that I can connect and send stuff. But I have no clue how to do that without having the proper UUID and service. Here is the peripheral Info
{
"characteristics":[
{
"properties":{
"Read":"Read"
},
"characteristic":"2a00",
"service":"1800"
},
{
"properties":{
"Read":"Read"
},
"characteristic":"2a01",
"service":"1800"
},
{
"properties":{
"Read":"Read"
},
"characteristic":"2a04",
"service":"1800"
},
{
"properties":{
"Read":"Read"
},
"characteristic":"2a29",
"service":"180a"
},
{
"properties":{
"Read":"Read"
},
"characteristic":"2a24",
"service":"180a"
},
{
"properties":{
"Read":"Read"
},
"characteristic":"2a25",
"service":"180a"
},
{
"properties":{
"Read":"Read"
},
"characteristic":"2a27",
"service":"180a"
},
{
"properties":{
"Read":"Read"
},
"characteristic":"2a26",
"service":"180a"
},
{
"properties":{
"Read":"Read"
},
"characteristic":"2a28",
"service":"180a"
},
{
"properties":{
"Read":"Read"
},
"characteristic":"2a23",
"service":"180a"
},
{
"properties":{
"Read":"Read"
},
"characteristic":"2a2a",
"service":"180a"
},
{
"properties":{
"Write":"Write",
"Read":"Read"
},
"characteristic":"49535343-6daa-4d02-abf6-19569aca69fe",
"service":"49535343-fe7d-4ae5-8fa9-9fafd205e455"
},
{
"descriptors":[
{
"value":null,
"uuid":"2902"
}
],
"properties":{
"Notify":"Notify",
"Write":"Write"
},
"characteristic":"49535343-aca3-481c-91ec-d85e28a60318",
"service":"49535343-fe7d-4ae5-8fa9-9fafd205e455"
},
{
"descriptors":[
{
"value":null,
"uuid":"2902"
}
],
"properties":{
"Indicate":"Indicate",
"Notify":"Notify"
},
"characteristic":"fff1",
"service":"fff0"
},
{
"properties":{
"Write":"Write",
"WriteWithoutResponse":"WriteWithoutResponse"
},
"characteristic":"fff2",
"service":"fff0"
}
],
"services":[
{
"uuid":"1800"
},
{
"uuid":"180a"
},
{
"uuid":"49535343-fe7d-4ae5-8fa9-9fafd205e455"
},
{
"uuid":"fff0"
}
],
"advertising":{
"txPowerLevel":2,
"serviceData":{
},
"serviceUUIDs":[
"fff0"
],
"localName":"FGT19100003",
"isConnectable":true,
"manufacturerData":{
"bytes":[
2,
1,
2,
12,
9,
70,
71,
84,
49,
57,
49,
48,
48,
48,
48,
51,
3,
3,
240,
255,
2,
10,
2,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"data":"AgECDAlGR1QxOTEwMDAwMwMD8P8CCgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
"CDVType":"ArrayBuffer"
}
},
"rssi":-48,
"id":"88:1B:99:25:AD:54",
"name":"FGT19100003"
But I see characteristic with just 4 chars. Now to my knowledge they have a format of XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX. I have gotten some source code in JAVA that I can upload if anyone wants to have a look at it (it works I installed it and it can scan the fingerprint and gives me the BitMatrix of it back.) (src java project: https://filebin.net/7jeo1o0lkgd8x2oy)
Here is the code for the function that I use in RN.
test(peripheral: { connected: any; id: string; }) {
if (peripheral) {
if (peripheral.connected) {
BleManager.disconnect(peripheral.id);
} else {
BleManager.connect(peripheral.id).then(() => {
let peripherals = this.state.peripherals;
let p = peripherals.get(peripheral.id);
if (p) {
p.connected = true;
peripherals.set(peripheral.id, p);
this.setState({ peripherals });
}
console.log('Connected to ' + peripheral.id);
setTimeout(() => {
BleManager.retrieveServices(peripheral.id).then((peripheralInfo) => {
console.log(JSON.stringify(peripheralInfo))
var service = '49535343-6daa-4d02-abf6-19569aca69fe';
var crustCharacteristic = '49535343-fe7d-4ae5-8fa9-9fafd205e455';
setTimeout(() => {
BleManager.startNotification(peripheral.id, service, crustCharacteristic).then(() => {
console.log('Started notification on ' + peripheral.id);
setTimeout(() => {
BleManager.write(peripheral.id, service, crustCharacteristic, [0]).then(() => {
console.log('write succes');
});
}, 500);
}).catch((error) => {
console.log('Notification error', error);
});
}, 200);
});
}, 900);
}).catch((error) => {
console.log('Connection error', error);
});
}
}
}
Does anyone have experiance with it? I also got a table that states which I think contains all possible commands (https://i.imgur.com/0TP0etn.png).
BLE Services & Characteristics that only have 16-bit UUIDs are the standards ones set by the Bluetooth SIG. They can be found here and here respectively. Most of the characteristics in that list are the standard ones, and I would bet the only one with a 128-bit UUID (0x49535343-fe7d-4ae5-8fa9-9fafd205e455) is the custom service for the finger print data, that or the 0xFFF0 service. They each have some characteristics with indicate/notify, so those are the ones that I imagine would have the data. 0xFFF0 is not a standard UUID, but it is often used in sample codes and implementation examples, but typically shouldn't be in a shipping product, but it has as much chance as being the right characteristic as the other one. I would try making an extra large data buffer, and setting the characteristics to notify/indicate in both services, then do a fingerprint test, and see what you get.
Alternatively, you can use one of the mobile phone BLE debug apps from Nordic (NRFconnect) or Cypress (CySmart) to do the same test and get an idea of the right characteristic by using your phone to perform the same test.

jsgrid need functionality to upload and show image

I am using jsGrid for showing data from database. But I am stuck with a problem.
All text field or select field are rendering correctly. But I need to add a custom field with functionality to add image on edit (when no image added) a row and show image on the field while page load using jsGrid. I searched the web but not find any solution to solve my issue.
This is how it could be implemented:
var data = [
{ Name: "John", Img: "http://placehold.it/250x250" },
{ Name: "Jimmy", Img: "http://placehold.it/250x250" },
{ Name: "Tom", Img: "http://placehold.it/250x250" },
{ Name: "Frank", Img: "http://placehold.it/250x250" },
{ Name: "Peter", Img: "http://placehold.it/250x250" }
];
$("#dialog").dialog({
modal: true,
autoOpen: false,
position: {
my: "center",
at: "center",
of: $("#jsgrid")
}
});
$("#jsgrid").jsGrid({
autoload: true,
width: 350,
filtering: true,
inserting: true,
controller: {
loadData: function(filter) {
return !filter.Name
? data
: $.grep(data, function(item) { return item.Name.indexOf(filter.Name) > -1; });
// use ajax request to load data from the server
/*
return $.ajax({
method: "GET",
url: "/YourUrlToAddItemFilteringScript",
data: filter
});
*/
},
insertItem: function(insertingItem) {
var formData = new FormData();
formData.append("Name", insertingItem.Name);
formData.append("Img[]", insertingItem.Img, insertingItem.Img.name);
return $.ajax({
method: "post",
type: "POST",
url: "/YourUrlToAddItemAndSaveImage",
data: formData,
contentType: false,
processData: false
});
}
},
fields: [
{
name: "Img",
itemTemplate: function(val, item) {
return $("<img>").attr("src", val).css({ height: 50, width: 50 }).on("click", function() {
$("#imagePreview").attr("src", item.Img);
$("#dialog").dialog("open");
});
},
insertTemplate: function() {
var insertControl = this.insertControl = $("<input>").prop("type", "file");
return insertControl;
},
insertValue: function() {
return this.insertControl[0].files[0];
},
align: "center",
width: 120
},
{ type: "text", name: "Name" },
{ type: "control", editButton: false }
]
});
Checkout the working fiddle http://jsfiddle.net/tabalinas/ccy9u7pa/16/
According issue on GitHub: https://github.com/tabalinas/jsgrid/issues/107