Media Source Extensions appendBuffer of WebM stream in random order - webm

I am trying to achieve video downloading in parallel from multiple sources. However MSE appendBuffer method always fails when not following sequence order of video file.
I would like to append parts in random order and play video "as soon as possible".
I was exploring SourceBuffer mode property as well as timestampOffset. None of those were helpful.
I am wondering if source webm file i have could be in "not supported format" for such a task (sequential approach works fine).
source video file
Thank you for any advices.
UPDATE:
I tried to analyse well known example video file and i figured out that it is possible to append parts of it out of order. Seems like it is necessary to follow Cluster byte ranges:
<Cluster type="list" offset="4357">
<Timecode type="uint" value="0"/>
<SimpleBlock type="binary" size="7723" trackNum="1" timecode="0" presentationTimecode="0" flags="80"/>
<SimpleBlock type="binary" size="5" trackNum="2" timecode="0" presentationTimecode="0" flags="80"/>
...
</Cluster>
<Cluster type="list" offset="16187">
<Timecode type="uint" value="385"/>
<SimpleBlock type="binary" size="5" trackNum="2" timecode="0" presentationTimecode="385" flags="80"/>
<SimpleBlock type="binary" size="4968" trackNum="1" timecode="13" presentationTimecode="398" flags="80"/>
...
</Cluster>

After digging into webm format specification, compiling libwebm tools and studying DASH i finally figured out how to make MSE appendBuffer working in any order!
ffmpeg -i result.webm -g 10 -c:v libvpx resultClusters.webm (you can also use libvpx-vp9)
mkvmuxer_sample -i resultClusters.webm -o resultRepaired.webm
mse_json_manifest resultRepaired.webm >> manifest.json
You will get on stdout something like:
{
"type": "video/webm; codecs=\"vp8\"",
"duration": 27771.000000,
"init": { "offset": 0, "size": 258},
"media": [
{ "offset": 258, "size": 54761, "timecode": 0.000000 },
{ "offset": 55019, "size": 166431, "timecode": 2.048000 },
{ "offset": 221450, "size": 49258, "timecode": 4.130000 },
{ "offset": 270708, "size": 29677, "timecode": 6.148000 },
{ "offset": 300385, "size": 219929, "timecode": 8.232000 },
{ "offset": 520314, "size": 25132, "timecode": 10.335000 },
{ "offset": 545446, "size": 180777, "timecode": 12.440000 },
{ "offset": 726223, "size": 76107, "timecode": 14.471000 },
{ "offset": 802330, "size": 376557, "timecode": 14.794000 },
{ "offset": 1178887, "size": 247138, "timecode": 16.877000 },
{ "offset": 1426025, "size": 78468, "timecode": 18.915000 },
{ "offset": 1504493, "size": 25614, "timecode": 20.991000 },
{ "offset": 1530107, "size": 368277, "timecode": 23.093000 },
{ "offset": 1898384, "size": 382847, "timecode": 25.097000 },
{ "offset": 2281231, "size": 10808, "timecode": 27.135000 }
]
}
Now all you have to do is firstly load metadata xhr.setRequestHeader("Range", "bytes=0-257"); and then in ANY ORDER all other segments. E.g. second segment range is 55019-221449 bytes.
Explanation:
The most important thing is ffmpeg reencoding with group of frames set to the size of cluster you would like to have. In this example i choose pretty low threshold (each 10 frames) but you can choose higher causing fewer clusters are generated (less items in "media" array).
After that you have to fix cues in the classic way (using sample_muxer from libwebm) and you are ready to go.
Tested on: Chrome 51, Firefox 47.

Related

Bitcoin / DefiChain RPC rawTransaction

Hello i try to figure out how to encode normal rpc calls in an raw transaction.
Till now my problem is that i dont know what the hex must contain as string.
f.e.
rpc command: "method: 'compositeswap' {'from':'MyAddress','tokenFrom':'MyToken1','amountFrom':'0.001','to':'Address','tokenTo':'Token2','maxPrice':'0.01'}"
There seems to be OP-Codes to exists like OP_DEFI_TX_COMPOSITE_SWAP
how does the chain knows to execute an operation with params?
i tried to figure it out by trying to decode an actual transaction from the test wallet:
from the part
"scriptPubKey": {
"asm": "OP_RETURN 446654786917a914721d5b1c58d38af7b6797b385b6ac291b002f88c870000e1f5050000000017a914721d5b1c58d38af7b6797b385b6ac291b002f88c870b0000000000000000c74e71050000000000",
"hex": "6a4c50446654786917a914721d5b1c58d38af7b6797b385b6ac291b002f88c870000e1f5050000000017a914721d5b1c58d38af7b6797b385b6ac291b002f88c870b0000000000000000c74e71050000000000",
"type": "nulldata"
},
of
{
"txid": "9a98d693d4c5107647131ee1bb7a5b0cce0fcdbe390c9609a71f4b71157e39dc",
"hash": "a18a6fd4abf0ba1885febcf37a333b1d1f34b4de954f13538a6619b1d7b20042",
"version": 4,
"size": 309,
"vsize": 228,
"weight": 909,
"locktime": 0,
"vin": [
{
"txid": "9e1140197138ba5e247ab3b3f1f4881bf7be624a939073d9795242caf3634409",
"vout": 1,
"scriptSig": {
"asm": "0014451be7ab94ccd7eff0a33ab8fe997a75c62eb7dd",
"hex": "160014451be7ab94ccd7eff0a33ab8fe997a75c62eb7dd"
},
"txinwitness": [
"30440220552d8aa4e129f566bfe083b780e1dcf67a3ca0176e07407912451371f597bc620220698c6ac483e021b78c7d7bf42e14f1c619618d1941cf12fec7cf8302ece6d3ae01",
"03c7d2dbe5ee429de5d88e8594cda6ceb84268ebbf9d0b16b33664e999307f33e8"
],
"sequence": 4294967295
}
],
"vout": [
{
"value": 0,
"n": 0,
"scriptPubKey": {
"asm": "OP_RETURN 446654786917a914721d5b1c58d38af7b6797b385b6ac291b002f88c870000e1f5050000000017a914721d5b1c58d38af7b6797b385b6ac291b002f88c870b0000000000000000c74e71050000000000",
"hex": "6a4c50446654786917a914721d5b1c58d38af7b6797b385b6ac291b002f88c870000e1f5050000000017a914721d5b1c58d38af7b6797b385b6ac291b002f88c870b0000000000000000c74e71050000000000",
"type": "nulldata"
},
"tokenId": 0
},
{
"value": 183.03901748,
"n": 1,
"scriptPubKey": {
"asm": "OP_HASH160 721d5b1c58d38af7b6797b385b6ac291b002f88c OP_EQUAL",
"hex": "a914721d5b1c58d38af7b6797b385b6ac291b002f88c87",
"reqSigs": 1,
"type": "scripthash",
"addresses": [
"tgfbETCK2kYyvsnHbS41v9aicQzAXLsz9B"
]
},
"tokenId": 0
}
]
}
the
OP_RETURN 446654786917a914721d5b1c58d38af7b6797b385b6ac291b002f88c870000e1f5050000000017a914721d5b1c58d38af7b6797b385b6ac291b002f88c870b0000000000000000c74e71050000000000
cant be decoded sucessfully back into a string.
does s.o know what kind of encoding it is?
tried
bytess=bytes.fromhex("446654786917a914721d5b1c58d38af7b6797b385b6ac291b002f88c870000e1f5050000000017a914721d5b1c58d38af7b6797b385b6ac291b002f88c870b0000000000000000c74e71050000000000")
print(bytess.decode("latin-1"))
but only get
INFO (MainThread) 14.05.2022 22:02:39 DfTxi©r
INFO (MainThread) 14.05.2022 22:02:39 [
INFO (MainThread) 14.05.2022 22:02:39 XÓŠ÷¶y{8[j‘°øŒ‡ áõ ©r
You can't just decode the string after the OP Code. It is a concatenation of several input parameters depending on the function.
In your example
6a4c50446654786917a914721d5b1c58d38af7b6797b385b6ac291b002f88c870000e1f5050000000017a914721d5b1c58d38af7b6797b385b6ac291b002f88c870b0000000000000000c74e71050000000000
6a is OP_RETURN
4c50 is Number of bytes following (in HEX)
44665478 is "DfTx" in HEX
6917a914721d5b1c58d38af7b6797b385b6ac291b002f88c870000e1f5050000000017a914721d5b1c58d38af7b6797b385b6ac291b002f88c870b0000000000000000c74e71050000000000 = the parameters from your json. For your address you need Base58 (in this case) or Bech32 encoding to get the hex (some backward engineering necessary).
The part with lots of zeros is the amount/maxPrice.
The tokens are inserted by their IDs not the name.
I am thinking about writing a guide. So far, I am afraid you have to do some backward engineering. Hope this helps a little bit

How to load a specific Topojson with Vega

I am new to Vega and I would like to load this topojson with Vega :
https://github.com/deldersveld/topojson/blob/master/countries/france/fr-departments.json
I have already followed the airport tutorial but I dont know what to write in the "projections" and "format" field to insert my topojson.
Thanks,
This is a late response but posting as it could be useful for others.
Here are the key attributes/changes for the map to work:
"feature": "FRA_adm2" in data[0].format. I picked this from the topojson's objects key
"field": "properties.ID_1". Important for scale, legend, map fill. I picked this from the topojson's objects.FRA_adm2.geometries[0].properties, assuming that's the unique sub-region key.
define a projection and use it the mark's transform attribute
...
"data": [{
"name": "table",
"url": "https://raw.githubusercontent.com/deldersveld/topojson/master/countries/france/fr-departments.json",
"format": {"type": "topojson", "feature": "FRA_adm2"}
}],
...
"projections": [{
"name": "projection",
"size": {"signal": "[width, height]"},
"fit": {"signal": "data('table')"},
"type": "mercator"
}],
...
"marks": [{
...
"transform": [{"type": "geoshape", "projection": "projection"}]
}]
...
specification
Vega specification: link

Loading data from external API in Vega

When I try to change https://vega.github.io/editor/#/examples/vega/scatter-plot like,
- "url": "data/cars.json"
+ "url": "http://dummy.restapiexample.com/api/v1/employees",
I get an error,
loader.js:166 Mixed Content: The page at 'https://vega.github.io/editor/#/edited' was loaded over HTTPS, but requested an insecure resource 'http://dummy.restapiexample.com/api/v1/employees'. This request has been blocked; the content must be served over HTTPS.
How do I fetch data from an external API?
Pretty simple. I just needed to use the same protocol HTTPS --> HTTPS
{
"$schema": "https://vega.github.io/schema/vega-lite/v3.json",
"description": "A scatterplot showing horsepower and miles per gallons for various cars.",
"data": {"url": "https://jsonplaceholder.typicode.com/todos"},
"mark": "point",
"encoding": {
"x": {"field": "userId","type": "quantitative"},
"y": {"field": "id","type": "quantitative"}
}
}

Latest one video uploaded in youtube channel

I need to show the thumbnail of the latest video on my youtube channel on my website and add a link to that video. While using the API parameter date it's showing the first video in that channel. Instead of that, I need the last published video details how to solve this
This is what I used as I require only one last video
https://www.googleapis.com/youtube/v3/search?key=[key]&channelId=[channel-id]&part=snippet,id&order=relevance&maxResults=1
(option 1)
You could try replacing order=relevance with order=date
try:
https://www.googleapis.com/youtube/v3/search?key=[key]&channelId=[channel-id]&part=snippet,id&order=date&maxResults=1
(option 2)
You could also try using publishedAfter command (which takes a year-month-day format).
Example: publishedAfter=2019-03-25T00:00:00Z (because yesterday was March 25th).
try:
https://www.googleapis.com/youtube/v3/search?key=[key]&channelId=[channel-id]&part=snippet,id&publishedAfter=2019-03-25T00:00:00Z&order=date&maxResults=1
(option 3)
Use your programming language to fetch / read the HTML source-code of the channel's uploads page. The first thumbnail listed after gridVideoRenderer is the latest, along with relevant URL.
Example steps:
1) Go to user's uploads page and use "view source" option to see the HTML text (source code).
This text is what your programming language should show you when you http request the link of the channel's uploads.
https://www.youtube.com/user/MARVEL/videos
2) After acquiring (or viewing) the source code
From there find position of the word gridVideoRenderer.
Then starting after position, now find the first occurence of word "url":".
That is the URL. Extract manually by hand or write code to do it automatically.
PS: Replace any unicode in the link, like \u0026 with &.
https://i.ytimg.com/vi/QuP7V2gKgPI/hqdefault.jpg?sqp=-oaymwEZCPYBEIoBSFXyq4qpAwsIARUAAIhCGAFwAQ==&rs=AOn4CLDBeSfAIiCdLDKtA8h2G-AZqk-xhQ
I tried "option 1" with my own Key, and got the correct response as far as which "video" from the "Channel" - NO THUMBNAILs, just references to it/them, code follows:
{
"kind": "youtube#searchListResponse",
"etag": "EymHvUd1w4o13UcSUT0C9YINu3o",
"nextPageToken": "CAEQAA",
"regionCode": "US",
"pageInfo": {
"totalResults": 181,
"resultsPerPage": 1
},
"items": [
{
"kind": "youtube#searchResult",
"etag": "23QGL4Y9Du8EXMntX5ZNdr1F7_k",
"id": {
"kind": "youtube#video",
"videoId": "RRQjUvoSuKU"
},
"snippet": {
"publishedAt": "2022-11-13T15:09:07Z",
"channelId": "UCbhMYK2QQXgHjgnMN3zegRQ",
"title": "All Things Closely",
"description": "Luke 1:1-4.",
"thumbnails": {
"default": {
"url": "https://i.ytimg.com/vi/RRQjUvoSuKU/default.jpg",
"width": 120,
"height": 90
},
"medium": {
"url": "https://i.ytimg.com/vi/RRQjUvoSuKU/mqdefault.jpg",
"width": 320,
"height": 180
},
"high": {
"url": "https://i.ytimg.com/vi/RRQjUvoSuKU/hqdefault.jpg",
"width": 480,
"height": 360
}
},
"channelTitle": "Restoration Church Homestead",
"liveBroadcastContent": "none",
"publishTime": "2022-11-13T15:09:07Z"
}
}
]
}
THAT's all that showed on a browser page, no Thumbnails-just code, but could not figure out how to get any code in the string to PLAY that video ...
any ideas?
I would love to just have it as a LINK rather than any other scripts loaded on the server. I'm missing something, probably simple I bet, to get the returned video related to the data to play.

How to Get Twitch Video Thumbnail URL?

Video-sharing websites such as Youtube has a endpoint for video thumbnails
Example: http://img.youtube.com/vi/youtube_id/default.jpg
where youtube_id = the id of the video
So I can just do
<img src="http://img.youtube.com/vi/youtube_id/default.jpg">
with no problem
Does twitch have something like this as well?
Update 2018
Twitch requires you to use its API so you can get access to video thumbnails. Apparently, this is because the URL of the thumbnails may change
Here is a simple guide how to get access to a twitch video thumbnail
You have to get access to Twitch dev API - to do this you need to register an account at https://glass.twitch.tv
After registering an account you must then create an App from your twitch dev dashboard
After creating the App, you will be given a Client ID to be used for that app - note that the app is the one which will be using the twitch API (for example, your website)
You can now pass the client_id as a query string parameter to https://api.twitch.tv/kraken/videos/106400740?client_id=xxxxxxx where 106400740 is the video id (note that 'kraken' here is constant - not sure of the origin behind its name) - note that the request will return a JSON object which contains an error message if you do not include a client_id
The request will return a JSON object which looks something like:
{
"title": "Door 5 vs Tilted Gamers",
"description": "COOL Games: Killing Spree first match # Mineski. Grove, Los Ba\u00f1os",
"description_html": "COOL Games: Killing Spree first match # Mineski. Grove, Los Ba\u00f1os<br>",
"broadcast_id": 1,
"broadcast_type": "upload",
"status": "recorded",
"language": "en",
"tag_list": "",
"views": 4,
"created_at": "2017-11-08T03:13:12Z",
"published_at": "2017-11-08T04:33:37Z",
"url": "https:\/\/www.twitch.tv\/videos\/188543310",
"_id": "v188543310",
"recorded_at": "2017-11-08T03:13:12Z",
"game": "Dota 2",
"length": 2436,
"preview": "https:\/\/static-cdn.jtvnw.net\/s3_vods\/esportsdotcool\/188543310\/3534ab8c-bf7d-4c8a-b502-c406825bf75f\/thumb\/index-0000000000-320x240.jpg",
"animated_preview_url": "https:\/\/vod-storyboards.twitch.tv\/esportsdotcool\/188543310\/3534ab8c-bf7d-4c8a-b502-c406825bf75f\/storyboards\/188543310-strip-0.jpg",
"thumbnails": [
{
"type": "generated",
"url": "https:\/\/static-cdn.jtvnw.net\/s3_vods\/esportsdotcool\/188543310\/3534ab8c-bf7d-4c8a-b502-c406825bf75f\/thumb\/index-0000000000-320x240.jpg"
},
{
"type": "generated",
"url": "https:\/\/static-cdn.jtvnw.net\/s3_vods\/esportsdotcool\/188543310\/3534ab8c-bf7d-4c8a-b502-c406825bf75f\/thumb\/index-0000000006-320x240.jpg"
},
{
"type": "generated",
"url": "https:\/\/static-cdn.jtvnw.net\/s3_vods\/esportsdotcool\/188543310\/3534ab8c-bf7d-4c8a-b502-c406825bf75f\/thumb\/index-0000000012-320x240.jpg"
},
{
"type": "generated",
"url": "https:\/\/static-cdn.jtvnw.net\/s3_vods\/esportsdotcool\/188543310\/3534ab8c-bf7d-4c8a-b502-c406825bf75f\/thumb\/index-0000000018-320x240.jpg"
}
],
"fps": {
"144p30": 29.999544341896,
"360p30": 29.999544341896,
"480p30": 29.999544341896
},
"resolutions": {
"144p30": "256x144",
"360p30": "640x360",
"480p30": "852x480"
},
"channel": {
"name": "esportsdotcool",
"display_name": "esportsdotcool"
},
"_links": {
"self": "https:\/\/api.twitch.tv\/kraken\/videos\/v188543310",
"channel": "https:\/\/api.twitch.tv\/kraken\/channels\/esportsdotcool"
}
}
Under the thumbnails array you can find the url to the video.
PS: As you can see, the thumbnails array has length of 4 - at this point I think this is because of the different sizes of the image that the author of the video can put up