Agora: Why my m3u8 file does not contain timestamp? - agora.io

I'm using agora composition recording and want to retrieve the start timestamp to build Synchronous playback.
The document says You can find the start timestamp at the start of each M3U8 file, however my M3U8 file does not contain any timestamp.
I can convert the output files (ts and m3u8) to mp4 by ffmpeg as expected.
The request body for start api is below;
const url = `${agoraApi}/v1/apps/${appId}/cloud_recording/resourceid/${resourceId}/mode/mix/start`
const body = {
cname,
uid,
clientRequest: {
token,
storageConfig: {
vendor: 1, // Amazon S3,
region: 10, // AP_NORTHEAST_1
accessKey: process.env.AWS_ACCESS_KEY_ID,
secretKey: process.env.AWS_SECRET_ACCESS_KEY,
bucket: process.env.AWS_S3_BUCKET,
fileNamePrefix: ["records"],
},
recordingConfig: {
channelType: 1, // default. 0: Communication profile, 1: Live broadcast profile
// maxIdleTime: 30, // seconds (default)
transcodingConfig: {
width: 640, // default
height: 360, // default
fps: 15, // default
bitrate: 600,
mixedVideoLayout: 0, // default
},
},
},
};
The output M3U8 file
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:18
#EXTINF:16.038000
8893be119d40bbc66f7ef9a26a676a12_live-aea67a87-f821-4234-894b-1512fcdae181_20210603064340040.ts
#EXTINF:15.972000
8893be119d40bbc66f7ef9a26a676a12_live-aea67a87-f821-4234-894b-1512fcdae181_20210603064357105.ts
#EXTINF:16.038000
8893be119d40bbc66f7ef9a26a676a12_live-aea67a87-f821-4234-894b-1512fcdae181_20210603064413077.ts
#EXTINF:15.971000
8893be119d40bbc66f7ef9a26a676a12_live-aea67a87-f821-4234-894b-1512fcdae181_20210603064429115.ts
#EXTINF:16.039000
8893be119d40bbc66f7ef9a26a676a12_live-aea67a87-f821-4234-894b-1512fcdae181_20210603064445086.ts
#EXTINF:15.972000
8893be119d40bbc66f7ef9a26a676a12_live-aea67a87-f821-4234-894b-1512fcdae181_20210603064501125.ts
#EXTINF:15.972000
8893be119d40bbc66f7ef9a26a676a12_live-aea67a87-f821-4234-894b-1512fcdae181_20210603064517097.ts
#EXTINF:16.038000
8893be119d40bbc66f7ef9a26a676a12_live-aea67a87-f821-4234-894b-1512fcdae181_20210603064533069.ts
#EXTINF:15.972000
8893be119d40bbc66f7ef9a26a676a12_live-aea67a87-f821-4234-894b-1512fcdae181_20210603064549107.ts
#EXTINF:16.038000
8893be119d40bbc66f7ef9a26a676a12_live-aea67a87-f821-4234-894b-1512fcdae181_20210603064605079.ts
#EXTINF:15.972000
8893be119d40bbc66f7ef9a26a676a12_live-aea67a87-f821-4234-894b-1512fcdae181_20210603064621117.ts
#EXTINF:16.038000
8893be119d40bbc66f7ef9a26a676a12_live-aea67a87-f821-4234-894b-1512fcdae181_20210603064637088.ts
#EXTINF:11.679000
8893be119d40bbc66f7ef9a26a676a12_live-aea67a87-f821-4234-894b-1512fcdae181_20210603064653127.ts
#EXT-X-ENDLIST
Am i missing some configuration?

While you are correct to point out that there is no Epoch/Unix timestamp, there is a "timestamp" included the name of each segment. If you notice at the end of the name of the segments, is a human readable date and time.
for example, the first .ts file is named:
8893be119d40bbc66f7ef9a26a676a12_live-aea67a87-f821-4234-894b-1512fcdae181_20210603064340040.ts
If you split the name using the _ as the delimiter, the last element of the array is your timestamp. using the above name for example, the time-stamp would be 20210603064340040.
Taking this further you can break this down as:
yyyy mm dd hh mm ss ms
------------------------
2021 06 03 06 43 40 040
Using the next three files in the list we can see
8893be119d40bbc66f7ef9a26a676a12_live-aea67a87-f821-4234-894b-1512fcdae181_20210603064357105.ts
8893be119d40bbc66f7ef9a26a676a12_live-aea67a87-f821-4234-894b-1512fcdae181_20210603064413077.ts
8893be119d40bbc66f7ef9a26a676a12_live-aea67a87-f821-4234-894b-1512fcdae181_20210603064429115.ts
yyyy mm dd hh mm ss ms
------------------------
2021 06 03 06 43 57 105
2021 06 03 06 44 13 077
2021 06 03 06 44 29 115

Related

Wrong time being returned by date-fns when involving 2 timezones

Introduction
I have the current situation:
I receive the date from the backend as UTC
The user can have in his own profile his timezone setup
User can pick the date and time in two different time pickers
As soon as the date is returned by the backend I convert it to the user local timezone (timezone of his profile)
User selects new date, I create a zonedDate, modify it and store it as UTC
User selects new time, I use the utcToZonedTime to convert to user's local timezone (the UTC returned from backend), then I update with setHours and setMinutes and store back as UTC using toISOString() string
How the code is structured
I currently have the following code for when the user pick the date
import utcToZonedTime from 'date-fns-tz/utcToZonedTime';
const localizedTime = computed(() =>
utcToZonedTime(record.value.date, loggedUser.timezone)
);
const date = computed({
get: () => formatToDate(localizedTime.value),
set: (value: string) => {
// The `value` will come as YYYY-MM-DD from the DatePicker component
const zonedDateString = `${value}T17:30`;
const zonedDate = toDate(zonedDateString, {
timeZone: loggedUser.timezone,
});
record.value.date = zonedDate.toISOString();
},
});
This works fine for now. I set the hour and minutes to a hardcoded 17:30.
Now, the problem happens whenever picks the time:
import utcToZonedTime from 'date-fns-tz/utcToZonedTime';
import setMinutes from 'date-fns/setMinutes';
import setHours from 'date-fns/setHours';
const localizedTime = computed(() =>
utcToZonedTime(record.value.date, loggedUser.timezone)
);
const time = computed({
get: () => format(localizedTime.value, 'HH:mm'),
set: (time: string) => {
// Time is returned as HH:mm from the input
const [hour, minutes] = time.split(':');
console.log('Localized time:')
console.log(localizedTime.value);
let currentDateParsed = setHours(
localizedTime.value,
hour as unknown as number
);
currentDateParsed = setMinutes(
currentDateParsed,
minutes as unknown as number
);
console.log('Current date parsed:')
console.log(currentDateParsed);
record.value.date = currentDateParsed.toISOString();
},
});
Problem
As a setup I have the following criterias:
User timezone is set to Europe/Lisbon (GMT+1)
My computer timezone is set to Europe/Zagreb (GMT+2)
I receive the following date from backend in UTC 2022-06-02T16:00:56.000000Z
Time is displayed as 17:00 (I'm using the user profile's timezone and not the computer's timezone)
Whenever I set the date, it works perfect time. Whenever I try to set hours and minutes, the timezones get mixed up.
I select the time as 18:30 and it is displayed back to the user as 17:30.
The part of the code that is giving me problems is:
const time = computed({
get: () => format(localizedTime.value, 'HH:mm'),
set: (time: string) => {
// Time is returned as HH:mm from the input
const [hour, minutes] = time.split(':');
console.log('Localized time:')
console.log(localizedTime.value); 👈 // Thu Jun 02 2022 17:00:56 GMT+0200 (Central European Summer Time)
let currentDateParsed = setHours(
localizedTime.value,
hour as unknown as number
);
currentDateParsed = setMinutes(
currentDateParsed,
minutes as unknown as number
);
console.log('Current date parsed:')
console.log(currentDateParsed); 👈 // Thu Jun 02 2022 18:30:56 GMT+0200 (Central European Summer Time)
console.log('Current date parsed toISOString():');
console.log(currentDateParsed.toISOString()); 👈 // 2022-06-02T16:00:56.000Z
record.value.date = currentDateParsed.toISOString();
},
});
I have tried converting the date back to UTC and work only in UTC and also only in user's local time but nothing seems to work. I have uploaded the following video showing the issue

Cannot open Realm database in React Native using Realm Studio

I create, open and write on a realm database using following functions:
To load the database or to create a new one I am using:
let realm = new Realm({
path: 'UserDatabase.realm',
schema: [
{
name: 'user_details',
properties: {
user_id: {type: 'int', default: 0},
user_name: 'string',
user_contact: 'string',
user_address: 'string',
},
},
],
});
Write some data:
let realmWrite = () => {
if (realm === null || realm === undefined) {
console.error('realm is:' + realm);
} else {
realm.write(() => {
var ID = 1;
realm.create('user_details', {
user_id: ID,
user_name: 'username' + ID,
user_contact: 'contact',
user_address: `asd${ID}#asd.asd`,
});
});
}
};
Apparently writing data doesn't work, so I try to open the database using Realm Studio and I get following errors:
CLASSES
Unable to open a realm at path '/Users/shinigami/Library/Developer/CoreSimulator/Devices/DEB97125-E440-4AAA-9326-7E2B8D29F158/data/Containers/Data/Application/F2B137EF-F864-454D-A622-184C95C39EEE/Documents/UserDatabase.realm': Invalid top array (ref: 1080, size: 11)
Exception backtrace:
0 .io.realm.realm-studio.SwVRf2 0x000000010dcfe581 _ZN5realm15InvalidDatabaseC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_ + 49
1 .io.realm.realm-studio.SwVRf2 0x000000010dcec970 _ZN5realm5Group18validate_top_arrayERKNS_5ArrayERKNS_9SlabAllocE + 1632
2 .io.realm.realm-studio.SwVRf2 0x000000010dcf6a20 _ZN5realm11SharedGroup7do_openERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEbbNS_18SharedGroupOptionsE + 5136
3 .io.realm.realm-studio.SwVRf2 0x000000010d9f9a8c _ZN5realm11SharedGroup4openERNS_11ReplicationENS_18SharedGroupOptionsE + 236
4 .io.realm.realm-studio.SwVRf2 0x000000010d9f9473 _ZN5realm11SharedGroupC2ERNS_11ReplicationENS_18SharedGroupOptionsE + 1587
5 .io.realm.realm-studio.SwVRf2 0x000000010d964951 _ZN5realm5Realm16open_with_configERKNS0_6ConfigERNSt3__110unique_ptrINS_11ReplicationENS4_14default_deleteIS6_EEEERNS5_INS_11SharedGroupENS7_ISB_EEEERNS5_INS_5GroupENS7_ISF_EEEEPS0_ + 1145
6 .io.realm.realm-studio.SwVRf2 0x000000010d964286 _ZN5realm5RealmC2ENS0_6ConfigENSt3__110shared_ptrINS_5_impl16RealmCoordinatorEEE + 278
7 .io.realm.realm-studio.SwVRf2 0x000000010d984a40 _ZZN5realm5Realm17make_shared_realmENS0_6ConfigENSt3__110shared_ptrINS_5_impl16RealmCoordinatorEEEEN19make_shared_enablerC2ES1_S6_ + 84
8 .io.realm.realm-studio.SwVRf2 0x000000010d96ab44 _ZNSt3__110shared_ptrIZN5realm5Realm17make_shared_realmENS2_6ConfigENS0_INS1_5_impl16RealmCoordinatorEEEE19make_shared_enablerE11make_sharedIJS3_S6_EEES8_DpOT_ + 136
9 .io.realm.realm-studio.SwVRf2 0x000000010d97fa3c _ZN5realm5_impl16RealmCoordinator12do_get_realmENS_5Realm6ConfigERNSt3__110shared_ptrIS2_EERNS4_11unique_lockINS4_5mutexEEEb + 260
10 .io.realm.realm-studio.SwVRf2 0x000000010d97f8aa _ZN5realm5_impl16RealmCoordinator9get_realmENS_5Realm6ConfigE + 352
11 .io.realm.realm-studio.SwVRf2 0x000000010d9665fb _ZN5realm5Realm16get_shared_realmENS0_6ConfigE + 113
12 .io.realm.realm-studio.SwVRf2 0x000000010d8cb2cb _ZN5realm2js10RealmClassINS_4node5TypesEE19create_shared_realmEPN2v87IsolateENS_5Realm6ConfigEbONSt3__13mapINSA_12basic_stringIcNSA_11char_traitsIcEENSA_9allocatorIcEEEENSB_ISH_NS0_9ProtectedINS5_5LocalINS5_5ValueEEEEENSA_4lessISH_EENSF_INSA_4pairIKSH_SM_EEEEEESO_NSF_INSP_ISQ_ST_EEEEEEONSB_ISH_NSI_INSJ_INS5_8FunctionEEEEESO_NSF_INSP_ISQ_S10_EEEEEE + 127
13 .io.realm.realm-studio.SwVRf2 0x000000010d8c96c6 _ZN5realm2js10RealmClassINS_4node5TypesEE11constructorEPN2v87IsolateENS5_5LocalINS5_6ObjectEEERNS0_9ArgumentsIS3_EE + 402
14 .io.realm.realm-studio.SwVRf2 0x000000010d8c8a1b _ZN5realm4node10ObjectWrapINS_2js10RealmClassINS0_5TypesEEEE9constructERKN3Nan20FunctionCallbackInfoIN2v85ValueEEE + 333
15 .io.realm.realm-studio.SwVRf2 0x000000010d8c9412 _ZN3Nan3impL23FunctionCallbackWrapperERKN2v820FunctionCallbackInfoINS1_5ValueEEE + 166
16 Electron Framework 0x0000000102c1e4a8 _ZN2v88internallsERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEERKNS0_18BasicBlockProfilerE + 350504
...
What's wrong?
Update
Inspecting manually the realm file I see that the file is written and filled "as expected". Please, note username and asd1#asd.asd that are literal strings from the writing function.
I solved by updating Realm Studio to its beta version.
From:
to:
This because I was trying to open a v4 Realm JS file by using with the latest version of Studio which uses Realm JS v3 internally. So I have had to download and use the beta version of Realm Studio, which uses v4.

LdapJS server exop handling fails

I am using the LDAP server functionality of the Node.js module ldapjs version 1.0.2. I want to handle an LDAP 1.3.6.1.4.1.4203.1.11.1 extended operation (see RFC 3062 = LDAP Password Modify).
My server is configured...
const server = ldapjs.createServer( ... );
...
server.exop('1.3.6.1.4.1.4203.1.11.1', (req: any, res: any, next: any) => {
const requestValue = req.requestValue;
});
Calling the command ldappasswd (from debian package ldap-utils) works, handler method is called in proper way.
The data from the ldappasswd ... uid=user -A -S command with "old" as old password and "new" with new password results in the following hex values:
30 14 80 08 75 69 64 3d 73 75 72 66 81 03 6f 6c 64 82 03 6e 65 77
0 u i d = u s e r o l d n e w
0x80 marks the beginning of the attribute, 0x81 the beginning of the old password, 0x82 the beginning of the new password. The value after this byte is the length, followed by the information itself.
The problem:
Inside the handler methode, requestValue is a string with invalid separator characters.
0uid=user�old�new
Converting the string to a buffer ( Buffer.from(req.reuqestValue ) results in:
<Buffer 30 14 ef bf bd 08 75 69 64 3d 75 73 65 72 ef bf bd 03 6f 6c 64 ef bf bd 03 6e 65 77>
The separator bytes 0x80, 0x81 and 0x82 are converted to ef bf bd and therefore parsing information fails, because type is lost.
Any idea how to get out the information values from the requestValue attribute?
The problem can be solved by installing the version next and using req.requestValueBuffer instead of req.requestValue:
npm install --save ldapjs#next
const server = ldapjs.createServer( ... );
...
server.exop('1.3.6.1.4.1.4203.1.11.1', (req: any, res: any, next: any) => {
const requestValue = req.requestValueBuffer;
})
The problem is caused by a bug in the current ldapjs master branch (ad451edc) in file lib/messages/ext_request.js line 61:
this.requestName = ber.readString(0x80);
if (ber.peek() === 0x81)
try {
this.requestValue = ber.readString(0x81);
} catch (e) {
this.requestValue = ber.readBuffer(0x81);
}
In case of ldappasswd data the readString() function is called (no exception thrown), and this function always converts the buffer to a string using UTF-8 decoding. That's wrong. An additional bug in this code snippet is the call of readBuffer(...) which doesn't exist on the object ber.
In the branch next of the ldapjs repository this bug is solved by the bugfix in commit b87e4bb.
Bugfix lib/messages/ext_request.js line 82:
this.requestName = ber.readString(0x80)
if (ber.peek() === 0x81) {
this.requestValueBuffer = ber.readString(0x81, true)
this.requestValue = this.requestValueBuffer.toString('utf8')
}
A handler method can now use req.requestValueBuffer to get the original request data bytes.

React-big-calendar - sort(set order) allDay events

React big calendar receives an array with objects:
allDay: true
end: Sat Jan 13 2018 03:03:00 GMT+0200 (EET) {}
eventType: "video"
start: Sat Jan 13 2018 03:03:00 GMT+0200 (EET) {}
title: "0"
There can be 3 types of EventType - video, duration and audio,
but they are displaying completely in random order.
Image
Need an advice how to set an order?

results.total is undefined in dojo/store/JsonRest?

I am following one of dojo/store/JsonRest tutorial (https://dojotoolkit.org/reference-guide/1.10/dojo/store/JsonRest.html#dojo-store-jsonrest). As mentioned in the tutorial I am returning "Content-Range: items 0-24/66" in the header from server side (java).
I have tested in SOAP UI as well and the header is there in the server response:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Range: items 0-3/6
Content-Type: application/json
Content-Length: 402
Date: Thu, 16 Mar 2017 01:14:23 GMT
When I access the total as in following
var results = store.query({
start: 0,
count: 3
}).then(function (deals){
//do something
});
results.total.then(function(total){
//do something
});
Here I am getting results.total is undefined error. Any idea?
Please see screen shot is the content of results.
Content of Results
The returned total is available as a further promise on the returned promise of data which returns the total number of available rows indicated in the Content-Range: header as a number, so you can retrieve it like this:
var results = store.query({
start: 0,
count: 3
}).then(function(deals) {
// move this promise inside outer promise
results.total.then(function(total) {
//do something
});
});
Did a few more research and found out that following code can be used to get both response data and total. Not really sure why it wasn't working on above code blocks though.
var results = store.query({
start: 0,
count: 3
});
results.then(function (data) {
// You can access the response data here
results.total.then(function (total) {
// You can access total here
});
});