How to get the UTC date for when an image was uploaded using Images.get()? - dronedeploy

I am writing a plug-in to export/sync data from DroneDeploy.
I looked at the JSON that is returned from Images.get(). Sometimes a "date_creation" field is available. Sometimes that field is not present. Furthermore, within this field, a "$date" field shows what looks like a string based date which I have to assume is a local date? Is the representation of that date the local time of the user who uploaded the image? Or has it already been converted to the time zone of the user currently logged in?
Sample snipped JSON of an image coming from the Images.get() API:
{
"name": "camera",
"drone_session_id": "1495472258_SUPPORTOPENPIPELINE",
"command": "log",
"drone_device_id": "1495472258_SUPPORTOPENPIPELINE",
"date_creation": {
"$date": "2017:02:09 11:37:46"
}
}
How can I get a reliable true UTC date of when this image was uploaded to DroneDeploy so I can determine whether or not I should export the image if a user comes back and requests another sync operation to occur?

The image exif information you are referring can be a little unreliable due to which camera capture the images.
In order to determine which images you should sync I would recommend looking at which plans you have and haven't synced.
I.E.
const allPlanIds$ = dronedeployApi.Plans.all().then((plans) => plans.map((plan) => plan.id));
const alreadySyncedPlanIds$ = fetch()... // get these planIds from your server
const planIdsToSync$ = Promise.all(allPlanIds$, alreadySyncedPlanIds$).then(([planIds, syncedPlanIds]) => planIds.filter((planId) => !syncedPlanIds.includes(planId)));
planIdsToSync$.then((planIdsToSync) => console.log(planIdsToSync)) // get images for these planIds

Related

Can we store image in vuex? Should we do it?

I am trying to store profile thumbnail for easy access. Since I want to minimize resource consumption by eliminating the methods to fetch the image path every time the user reloads the page. Can we store image data in vuex? If so, should we do it?
Yes you can!
After the image response, pass the image to URL.createObjectURL() (Doc). This will cache the image in the browser and will give you a local image url, which you can then re-use:
const imageUrl: string = URL.createObjectURL(response.data);
if (imageUrl) {
// Update your store with an object like this:
{ id: imageId, url: imageUrl };
}
Then you can search your imageUrl[] state, where you saved this, by the id and retrieve the URL again.

Total duration not get in player using MP3 url when we pass header in 'react-native-track-player' in react native

I am using "react-native-track-player" for playing MP3 url in react native. But when I pass header authenticate at that time I am not able to get whole time of the MP3 url. In my screen it is necessary to show whole time of the url before player load. And also I am not able to do forward and backward action using "seekTO". for trackplayer the code is below,
var list = [currentItem].map(item => Object.assign(item,
{
artist: 'tootak',
headers: { Authorization: Global.authenticateUser },
url: item.is_local ?
('file://' + (item.url ? item.url : (item.URL ? item.URL : '')))
: Global.getMediaLink(item.url ? item.url : (item.URL ? item.URL : '')),
id: item.code,
artwork: Global.getUrl(item.images),
}))
await TrackPlayer.reset()
await TrackPlayer.add(list)
and for to seekTo ,
var time = await TrackPlayer.getposition()
await TrackPlayer.seekTo(time + 15)
They have referred to it in the docs that the library is only for streaming audio directly and to not depend on it to get something like duration.
react-native-track-player is a streaming library, which means it slowly buffers the track and doesn’t know exactly when it ends. The duration returned by this function is determined through various tricks and may not be exact or may not be available at all.
You should not trust this function. You should retrieve the duration from a database and feed it to the duration parameter in the Track Object.
We would need to use something like FFprobe or FFmpeg as a stream analyzer to retrieve the values. There is a package called get-audio-duration which does the job for you.

Using video.js is it possible to get current HLS timestamp?

I have an application which is embedding a live stream in it. To cater for delays I'd like to know what is the current timestamp of the stream and compare it with the time on the server.
What I have tested up till now is checking the difference between the buffered time of the video with the current time of the video:
player.bufferedEnd() - player.currentTime()
However I'd like to compare the time with the server instead and to do so I need to get the timestamp of the last requested .ts file.
So, my question is using video.js, is there some sort of hook to get the timestamp of the last requested .ts file?
Video.js version: 7.4.1
I had managed to solve this issue, however please bear with me I don't remember where I had found the documentation for this bit of code.
In my case I was working in an Angular application, I had a video component responsible for loading a live stream with the use of video.js. Anyway let's see some code...
Video initialisation
private videoInit() {
this.player = videojs('video', {
aspectRatio: this.videoStream.aspectRatio,
controls: true,
autoplay: false,
muted: true,
html5: {
hls: {
overrideNative: true
}
}
});
this.player.src({
src: '://some-stream-url.com',
type: 'application/x-mpegURL'
});
// on video play callback
this.player.on('play', () => {
this.saveHlsObject();
});
}
Save HLS Object
private saveHlsObject() {
if (this.player !== undefined) {
this.playerHls = (this.player.tech() as any).hls;
// get and syncing server time...
// make some request to get server time...
// then calculate difference...
this.diff = serverTime.getTime() - this.getVideoTime().getTime();
}
}
Get Timestamp of Video Segment
// access the player's playlists, get the last segment and extract time
// in my case URI of segments were for example: 1590763989033.ts
private getVideoTime(): Date {
const targetMedia = this.playerHls.playlists.media();
const lastSegment = targetMedia.segments[0];
const uri: string = lastSegment.uri;
const segmentTimestamp: number = +uri.substring(0, uri.length - 3);
return new Date(segmentTimestamp);
}
So above the main point is the getVideoTime function. The time of a segment can be found in the segment URI, so that function extracts the time from the segment URI and then converts it to a Date object. Now to be honest, I don't know if this URI format is something that's a standard for HLS or something that was set for the particular stream I was connecting to. Hope this helps, and sorry I don't have any more specific information!

How to hash image data in React-Native (Expo)?

My intent:
I want my app to upload images to S3. If image already exists, server should record a reference to existing image rather than asking for an upload of another copy.
How I imagine that works:
Hash image data
Send hash to server with request for signed url (to upload to AWS S3)
If hash matches something already stored, reference it and tell app
Initial thoughts:
Use imageEditor.cropImage to get image into ImageStore, which will give me an appropriate uri. Then use getBase64ForTag(uri, success, failure) to retrieve base64 data for a hash calculation.
The problem:
According to the answer on this question, this process is not efficient in the least. The usual solution would be to use native methods, as described in the answer to this question, however I do not want to eject my Expo app for this feature.
My Question:
Is there a better way to hash image data? Or more fundamentally, is there a better way of ensuring that identical images are not duplicated in S3 storage?
EDIT 2020-10-21 :
The library updated itself, and you should now call:
_hashImage = async (imageUri) => {
return await FileSystem.getInfoAsync(imageUri, { md5: true } );
}
ORIGINAL:
It turns out that Expo provides this out of the box.
Expo.FileSystem.getInfoAsync
myImageHashFunction = async (imageUri) => {
let fsInfo = await Expo.FileSystem.getInfoAsync(imageUri, [{ md5: true }] )
console.log(fsInfo.md5)
}
If you are still looking for a solution:
This is how I got it working - create a base64 of the image and then create a hash of it.
import * as FileSystem from 'expo-file-system';
import * as Crypto from 'expo-crypto';
let info = await FileSystem.readAsStringAsync(imageUri,
{ encoding: FileSystem.EncodingType.Base64 });
const hashData = await Crypto.digestStringAsync (
Crypto.CryptoDigestAlgorithm.MD5,
info
)

How do I get data from a background page to the content script in google chrome extensions

I've been trying to send data from my background page to a content script in my chrome extension. i can't seem to get it to work. I've read a few posts online but they're not really clear and seem quite high level. I've got managed to get the oauth working using the Oauth contacts example on the Chrome samples. The authentication works, i can get the data and display it in an html page by opening a new tab.
I want to send this data to a content script.
i'm having a lot of trouble with this and would really appreciate if someone could outline the explicit steps you need to follow to send data from a bg page to a content script or even better some code. Any takers?
the code for my background page is below (i've excluded the oauth paramaeters and other )
` function onContacts(text, xhr) {
contacts = [];
var data = JSON.parse(text);
var realdata = data.contacts;
for (var i = 0, person; person = realdata.person[i]; i++) {
var contact = {
'name' : person['name'],
'emails' : person['email']
};
contacts.push(contact); //this array "contacts" is read by the
contacts.html page when opened in a new tab
}
chrome.tabs.create({ 'url' : 'contacts.html'}); sending data to new tab
//chrome.tabs.executeScript(null,{file: "contentscript.js"});
may be this may work?
};
function getContacts() {
oauth.authorize(function() {
console.log("on authorize");
setIcon();
var url = "http://mydataurl/";
oauth.sendSignedRequest(url, onContacts);
});
};
chrome.browserAction.onClicked.addListener(getContacts);`
As i'm not quite sure how to get the data into the content script i wont bother posting the multiple versions of my failed content scripts. if I could just get a sample on how to request the "contacts" array from my content script, and how to send the data from the bg page, that would be great!
You have two options getting the data into the content script:
Using Tab API:
http://code.google.com/chrome/extensions/tabs.html#method-executeScript
Using Messaging:
http://code.google.com/chrome/extensions/messaging.html
Using Tab API
I usually use this approach when my extension will just be used once in a while, for example, setting the image as my desktop wallpaper. People don't set a wallpaper every second, or every minute. They usually do it once a week or even day. So I just inject a content script to that page. It is pretty easy to do so, you can either do it by file or code as explained in the documentation:
chrome.tabs.executeScript(tab.id, {file: 'inject_this.js'}, function() {
console.log('Successfully injected script into the page');
});
Using Messaging
If you are constantly need information from your websites, it would be better to use messaging. There are two types of messaging, Long-lived and Single-requests. Your content script (that you define in the manifest) can listen for extension requests:
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if (request.method == 'ping')
sendResponse({ data: 'pong' });
else
sendResponse({});
});
And your background page could send a message to that content script through messaging. As shown below, it will get the currently selected tab and send a request to that page.
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.sendRequest(tab.id, {method: 'ping'}, function(response) {
console.log(response.data);
});
});
Depends on your extension which method to use. I have used both. For an extension that will be used like every second, every time, I use Messaging (Long-Lived). For an extension that will not be used every time, then you don't need the content script in every single page, you can just use the Tab API executeScript because it will just inject a content script whenever you need to.
Hope that helps! Do a search on Stackoverflow, there are many answers to content scripts and background pages.
To follow on Mohamed's point.
If you want to pass data from the background script to the content script at initialisation, you can generate another simple script that contains only JSON and execute it beforehand.
Is that what you are looking for?
Otherwise, you will need to use the message passing interface
In the background page:
// Subscribe to onVisited event, so that injectSite() is called once at every pageload.
chrome.history.onVisited.addListener(injectSite);
function injectSite(data) {
// get custom configuration for this URL in the background page.
var site_conf = getSiteConfiguration(data.url);
if (site_conf)
{
chrome.tabs.executeScript({ code: 'PARAMS = ' + JSON.stringify(site_conf) + ';' });
chrome.tabs.executeScript({ file: 'site_injection.js' });
}
}
In the content script page (site_injection.js)
// read config directly from background
console.log(PARAM.whatever);
I thought I'd update this answer for current and future readers.
According to the Chrome API, chrome.extension.onRequest is "[d]eprecated since Chrome 33. Please use runtime.onMessage."
See this tutorial from the Chrome API for code examples on the messaging API.
Also, there are similar (newer) SO posts, such as this one, which are more relevant for the time being.