Skip to content

Instantly share code, notes, and snippets.

@Reino17
Created May 14, 2021 16:29
Show Gist options
  • Select an option

  • Save Reino17/4e8d02e1237ab0c77f761fab19d1f3f2 to your computer and use it in GitHub Desktop.

Select an option

Save Reino17/4e8d02e1237ab0c77f761fab19d1f3f2 to your computer and use it in GitHub Desktop.
Extract and download videos from Collegerama with Xidel and/or FFmpeg
SET url=https://collegerama.tudelft.nl/Mediasite/Play/585a43626e544bdd97aeb71a0ec907a01d?catalog=fd32fd35-6c99-466c-89d4-cd3c431bc8a4
------------------------------------------------------------------------------------------------
[JSON post data preparation]
"QueryString" is not really necessary.
xidel -se "('%url%',substring-before('%url%','?')) ! serialize({'getPlayerOptionsRequest':{'ResourceId':extract(.,'.+/([\da-z]+)',1),'QueryString':extract(.,'\?.+')}},{'method':'json'})"
{"getPlayerOptionsRequest":{"ResourceId":"585a43626e544bdd97aeb71a0ec907a01d","QueryString":"?catalog=fd32fd35-6c99-466c-89d4-cd3c431bc8a4"}}
{"getPlayerOptionsRequest":{"ResourceId":"585a43626e544bdd97aeb71a0ec907a01d","QueryString":""}}
------------------------------------------------------------------------------------------------
[API call with command line options]
xidel -s -H "Content-Type: application/json" -d "{serialize({'getPlayerOptionsRequest':{'ResourceId':extract('%url%','.+/([\da-z]+)',1),'QueryString':extract('%url%','\?.+')}},{'method':'json'})}" "https://collegerama.tudelft.nl/Mediasite/PlayerService/PlayerService.svc/json/GetPlayerOptions" -e "$json"
Prettified:
xidel -s ^
-H "Content-Type: application/json" ^
-d "{serialize({'getPlayerOptionsRequest':{'ResourceId':extract('%url%','.+/([\da-z]+)',1),'QueryString':extract('%url%','\?.+')}},{'method':'json'})}" ^
"https://collegerama.tudelft.nl/Mediasite/PlayerService/PlayerService.svc/json/GetPlayerOptions^" ^
-e "$json"
------------------------------------------------------------------------------------------------
["in-query" API call with x:request()]
xidel -se "('%url%',substring-before('%url%','?')) ! {'headers':'Content-Type: application/json','post':serialize({'getPlayerOptionsRequest':{'ResourceId':extract(.,'.+/([\da-z]+)',1),'QueryString':extract(.,'\?.+')}},{'method':'json'}),'url':'https://collegerama.tudelft.nl/Mediasite/PlayerService/PlayerService.svc/json/GetPlayerOptions'}"
{
"headers": "Content-Type: application/json",
"post": "{\"getPlayerOptionsRequest\":{\"ResourceId\":\"585a43626e544bdd97aeb71a0ec907a01d\",\"QueryString\":\"?catalog=fd32fd35-6c99-466c-89d4-cd3c431bc8a4\"}}",
"url": "https://collegerama.tudelft.nl/Mediasite/PlayerService/PlayerService.svc/json/GetPlayerOptions"
}
{
"headers": "Content-Type: application/json",
"post": "{\"getPlayerOptionsRequest\":{\"ResourceId\":\"585a43626e544bdd97aeb71a0ec907a01d\",\"QueryString\":\"\"}}",
"url": "https://collegerama.tudelft.nl/Mediasite/PlayerService/PlayerService.svc/json/GetPlayerOptions"
}
xidel -se "x:request({'headers':'Content-Type: application/json','post':serialize({'getPlayerOptionsRequest':{'ResourceId':extract('%url%','.+/([\da-z]+)',1),'QueryString':extract('%url%','\?.+')}},{'method':'json'}),'url':'https://collegerama.tudelft.nl/Mediasite/PlayerService/PlayerService.svc/json/GetPlayerOptions'})/json"
Prettified:
xidel -se ^"^
x:request({^
'headers':'Content-Type: application/json',^
'post':serialize(^
{^
'getPlayerOptionsRequest':{^
'ResourceId':extract('%url%','.+/([\da-z]+)',1),^
'QueryString':extract('%url%','\?.+')^
}^
},^
{'method':'json'}^
),^
'url':'https://collegerama.tudelft.nl/Mediasite/PlayerService/PlayerService.svc/json/GetPlayerOptions'^
})/json^
"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Save to a file:
xidel -se "[...]" > collegerama_585a43626e544bdd97aeb71a0ec907a01d.json
------------------------------------------------------------------------------------------------
[The JSON it returns (redacted)]
{
"d": {
[...]
"Presentation": {
"__type": "JsonDictionary:#SonicFoundry.Mediasite.Model.Serialization",
"Streams": [
{
"__type": "ManifestStream:#SonicFoundry.Mediasite.Model.Serialization",
"AnonymousAllowed": true,
"AspectRatio": 1.77777779,
"AudioOnly": false,
"HasSlideContent": true,
"IsStandAlone": false,
"PlaybackAudioSource": false,
"PreferFullMotion": false,
"Priority": 1,
"SlideBaseUrl": "https://collegerama.tudelft.nl/Mediasite/FileServer/d91dca0351ea4d579f07d9627b59a55c29/Presentation/585a43626e544bdd97aeb71a0ec907a01d/",
"SlideImageFileNameTemplate": "slide_{0:D4}.jpg",
"SlidePlaybackTicketId": "e73f25ff601744819e34ef88a167b4fd",
"SlideThumbnailFileNameTemplate": "",
"Slides": [
{
"__type": "ManifestSlide:#SonicFoundry.Mediasite.Model.Serialization",
"Description": "",
"Number": 1,
"StreamType": 2,
"Text": "",
"Time": 885
},
[...]
{
"__type": "ManifestSlide:#SonicFoundry.Mediasite.Model.Serialization",
"Description": "",
"Number": 54,
"StreamType": 2,
"Text": "",
"Time": 5013310
}
],
"StreamType": 2,
"ThumbnailUrl": "/Mediasite/FileServer/Presentation/585a43626e544bdd97aeb71a0ec907a01d/03ec7fc9-d074-4853-8add-6bf35ad08992.jpg?playbackTicket=e73f25ff601744819e34ef88a167b4fd",
"VideoUrls": []
},
{
"__type": "ManifestStream:#SonicFoundry.Mediasite.Model.Serialization",
"AnonymousAllowed": true,
"AspectRatio": 1.77777779,
"AudioOnly": false,
"HasSlideContent": false,
"IsStandAlone": false,
"PlaybackAudioSource": true,
"PreferFullMotion": true,
"Priority": 2,
"SlideBaseUrl": null,
"SlideImageFileNameTemplate": "slide_video1_{0:D4}.jpg",
"SlidePlaybackTicketId": "e73f25ff601744819e34ef88a167b4fd",
"SlideThumbnailFileNameTemplate": "",
"Slides": [],
"StreamType": 0,
"ThumbnailUrl": "/Mediasite/FileServer/Presentation/585a43626e544bdd97aeb71a0ec907a01d/95de53dd-6c84-4688-b887-927b8a8c877b.jpg?playbackTicket=e73f25ff601744819e34ef88a167b4fd",
"VideoUrls": [
{
"__type": "ManifestVideoUrl:#SonicFoundry.Mediasite.Model.Serialization",
"CanChangeScheme": true,
"Location": "https://collegerama-vs-ondemand-delft.tudelft.net/MediasiteDeliver/SSvideo/585a4362-6e54-4bdd-97ae-b71a0ec907a0/b7ead3b3-b74e-43d1-b643-22209a29ebfa.ism/manifest?playbackTicket=e73f25ff601744819e34ef88a167b4fd&site=collegerama.tudelft.nl",
"MediaType": "SS",
"MimeType": "video/x-mp4-fragmented",
"MulticastAddress": null,
"MulticastDiagnosticsServer": null,
"MulticastOnly": false,
"MulticastPort": 0,
"MulticastReceiverKeyStore": null,
"MulticastReceiverUrl": null,
"SegmentLength": 2000,
"ServerType": "Deliver"
},
{
"__type": "ManifestVideoUrl:#SonicFoundry.Mediasite.Model.Serialization",
"CanChangeScheme": true,
"Location": "https://collegerama-vs-ondemand-delft.tudelft.net/MediasiteDeliver/SSvideo/585a4362-6e54-4bdd-97ae-b71a0ec907a0/b7ead3b3-b74e-43d1-b643-22209a29ebfa.ism/manifest(format=m3u8-aapl-isoff,segmentLength=6)?playbackTicket=e73f25ff601744819e34ef88a167b4fd&site=collegerama.tudelft.nl",
"MediaType": "MP4",
"MimeType": "audio/x-mpegurl",
"MulticastAddress": null,
"MulticastDiagnosticsServer": null,
"MulticastOnly": false,
"MulticastPort": 0,
"MulticastReceiverKeyStore": null,
"MulticastReceiverUrl": null,
"SegmentLength": 6000,
"ServerType": "Deliver"
},
{
"__type": "ManifestVideoUrl:#SonicFoundry.Mediasite.Model.Serialization",
"CanChangeScheme": true,
"Location": "https://collegerama-vs-ondemand-delft.tudelft.net/MediasiteDeliver/SSvideo/585a4362-6e54-4bdd-97ae-b71a0ec907a0/b7ead3b3-b74e-43d1-b643-22209a29ebfa.ism/manifest(format=mpd-isoff,segmentLength=6)?playbackTicket=e73f25ff601744819e34ef88a167b4fd&site=collegerama.tudelft.nl",
"MediaType": "Dash",
"MimeType": "video/x-mpeg-dash",
"MulticastAddress": null,
"MulticastDiagnosticsServer": null,
"MulticastOnly": false,
"MulticastPort": 0,
"MulticastReceiverKeyStore": null,
"MulticastReceiverUrl": null,
"SegmentLength": 6000,
"ServerType": "Deliver"
},
{
"__type": "ManifestVideoUrl:#SonicFoundry.Mediasite.Model.Serialization",
"CanChangeScheme": true,
"Location": "https://collegerama-vs-ondemand-delft.tudelft.net/MediasiteDeliver/mp4/6775a61b-03df-418b-8fe0-f133cd90385c.mp4?playbackTicket=e73f25ff601744819e34ef88a167b4fd&site=collegerama.tudelft.nl",
"MediaType": "MP4",
"MimeType": "video/mp4",
"MulticastAddress": null,
"MulticastDiagnosticsServer": null,
"MulticastOnly": false,
"MulticastPort": 0,
"MulticastReceiverKeyStore": null,
"MulticastReceiverUrl": null,
"SegmentLength": 0,
"ServerType": "Deliver"
},
{
"__type": "ManifestVideoUrl:#SonicFoundry.Mediasite.Model.Serialization",
"CanChangeScheme": true,
"Location": "https://collegerama-vs-ondemand-delft.tudelft.net/MediasiteDeliver/mp4/6775a61b-03df-418b-8fe0-f133cd90385c.mp4/manifest(format=ms-sstr)?playbackTicket=e73f25ff601744819e34ef88a167b4fd&site=collegerama.tudelft.nl",
"MediaType": "SS",
"MimeType": "video/x-mp4-fragmented",
"MulticastAddress": null,
"MulticastDiagnosticsServer": null,
"MulticastOnly": false,
"MulticastPort": 0,
"MulticastReceiverKeyStore": null,
"MulticastReceiverUrl": null,
"SegmentLength": 2000,
"ServerType": "Deliver"
},
{
"__type": "ManifestVideoUrl:#SonicFoundry.Mediasite.Model.Serialization",
"CanChangeScheme": true,
"Location": "https://collegerama-vs-ondemand-delft.tudelft.net/MediasiteDeliver/mp4/6775a61b-03df-418b-8fe0-f133cd90385c.mp4/manifest(format=m3u8-aapl-isoff,segmentLength=6)?playbackTicket=e73f25ff601744819e34ef88a167b4fd&site=collegerama.tudelft.nl",
"MediaType": "MP4",
"MimeType": "audio/x-mpegurl",
"MulticastAddress": null,
"MulticastDiagnosticsServer": null,
"MulticastOnly": false,
"MulticastPort": 0,
"MulticastReceiverKeyStore": null,
"MulticastReceiverUrl": null,
"SegmentLength": 6000,
"ServerType": "Deliver"
},
{
"__type": "ManifestVideoUrl:#SonicFoundry.Mediasite.Model.Serialization",
"CanChangeScheme": true,
"Location": "https://collegerama-vs-ondemand-delft.tudelft.net/MediasiteDeliver/mp4/6775a61b-03df-418b-8fe0-f133cd90385c.mp4/manifest(format=mpd-isoff,segmentLength=6)?playbackTicket=e73f25ff601744819e34ef88a167b4fd&site=collegerama.tudelft.nl",
"MediaType": "Dash",
"MimeType": "video/x-mpeg-dash",
"MulticastAddress": null,
"MulticastDiagnosticsServer": null,
"MulticastOnly": false,
"MulticastPort": 0,
"MulticastReceiverKeyStore": null,
"MulticastReceiverUrl": null,
"SegmentLength": 6000,
"ServerType": "Deliver"
}
]
}
],
[...]
"PresentationId": "585a43626e544bdd97aeb71a0ec907a01d",
"Title": "Een nieuwe wereld: waarden, bewustzijn en techniek van de mensheid 2.0.",
"Description": "",
"ThumbnailUrl": "/Mediasite/FileServer/Presentation/585a43626e544bdd97aeb71a0ec907a01d/3cbc7aa4-5ba8-44b6-8554-09e396a79451.jpg",
"Duration": 7713088,
"AirDate": "14-10-2014",
"AirTime": "20:00 WEDT",
"UnixTime": 1413309600000,
[...]
"Presenters": [
{
"__type": "ManifestPresenter:#SonicFoundry.Mediasite.Model.Serialization",
"BioUrl": "",
"Email": "",
"ImageUrl": "",
"Name": "H. Wijffels"
}
],
"Transcript": [],
[...]
},
[...]
}
}
------------------------------------------------------------------------------------------------
["in-query" API call and JSON parsing (for a hypothetical copyright violating Xivid extractor)]
xidel -se "x:request({'headers':'Content-Type: application/json','post':serialize({'getPlayerOptionsRequest':{'ResourceId':extract('%url%','.+/([\da-z]+)',1),'QueryString':extract('%url%','\?.+')}},{'method':'json'}),'url':'https://collegerama.tudelft.nl/Mediasite/PlayerService/PlayerService.svc/json/GetPlayerOptions'})/json/d/Presentation/{'name':concat('Collegerama TU Delft: ',join(Presenters/Name,', '),' - ',Title),'date':round(UnixTime div 1000) * duration('PT1S') + dateTime('1970-01-01T00:00:00Z'),'duration':round(Duration div 1000) * duration('PT1S'),'formats':let $fmts:=(Streams)()[StreamType=0]/(VideoUrls)() return array{{'id':'pg-1','format':'mp4[h264+aac]','url':$fmts[MimeType='video/mp4']/Location},{'id':'dash-1','format':'mpd[h264+aac]','url':$fmts[MediaType='Dash'][2]/Location},{'id':'hls-1','format':'m3u8[h264+aac]','url':$fmts[MimeType='audio/x-mpegurl'][2]/Location}}}"
{
"name": "Collegerama TU Delft: H. Wijffels - Een nieuwe wereld: waarden, bewustzijn en techniek van de mensheid 2.0.",
"date": "2014-10-14T18:00:00Z",
"duration": "PT2H8M33S",
"formats": [
{
"id": "pg-1",
"format": "mp4[h264+aac]",
"url": "https://collegerama-vs-ondemand-delft.tudelft.net/MediasiteDeliver/mp4/6775a61b-03df-418b-8fe0-f133cd90385c.mp4?playbackTicket=e73f25ff601744819e34ef88a167b4fd&site=collegerama.tudelft.nl"
},
{
"id": "dash-1",
"format": "mpd[h264+aac]",
"url": "https://collegerama-vs-ondemand-delft.tudelft.net/MediasiteDeliver/mp4/6775a61b-03df-418b-8fe0-f133cd90385c.mp4/manifest(format=mpd-isoff,segmentLength=6)?playbackTicket=e73f25ff601744819e34ef88a167b4fd&site=collegerama.tudelft.nl"
},
{
"id": "hls-1",
"format": "m3u8[h264+aac]",
"url": "https://collegerama-vs-ondemand-delft.tudelft.net/MediasiteDeliver/mp4/6775a61b-03df-418b-8fe0-f133cd90385c.mp4/manifest(format=m3u8-aapl-isoff,segmentLength=6)?playbackTicket=e73f25ff601744819e34ef88a167b4fd&site=collegerama.tudelft.nl"
}
]
}
Prettified:
xidel -se ^"^
x:request({^
'headers':'Content-Type: application/json',^
'post':serialize(^
{^
'getPlayerOptionsRequest':{^
'ResourceId':extract('%url%','.+/([\da-z]+)',1),^
'QueryString':extract('%url%','\?.+')^
}^
},^
{'method':'json'}^
),^
'url':'https://collegerama.tudelft.nl/Mediasite/PlayerService/PlayerService.svc/json/GetPlayerOptions'^
})/json/d/Presentation/{^
'name':concat(^
'Collegerama TU Delft: ',^
join(Presenters/Name,', '),^
' - ',Title^
),^
'date':round(UnixTime div 1000) * duration('PT1S') + dateTime('1970-01-01T00:00:00Z'),^
'duration':round(Duration div 1000) * duration('PT1S'),^
'formats':let $fmts:=(Streams)()[StreamType=0]/(VideoUrls)() return array{^
{^
'id':'pg-1',^
'format':'mp4[h264+aac]',^
'url':$fmts[MimeType='video/mp4']/Location^
},^
{^
'id':'dash-1',^
'format':'mpd[h264+aac]',^
'url':$fmts[MediaType='Dash'][2]/Location^
},^
{^
'id':'hls-1',^
'format':'m3u8[h264+aac]',^
'url':$fmts[MimeType='audio/x-mpegurl'][2]/Location^
}^
}^
}^
"
------------------------------------------------------------------------------------------------
[Parse JSON and download video with Xidel / FFmpeg]
Progressive mp4:
xidel -s collegerama_585a43626e544bdd97aeb71a0ec907a01d.json -e "$json/d/Presentation/(Streams)()[StreamType=0]/(VideoUrls)()[MimeType='video/mp4']/Location"
https://collegerama-vs-ondemand-delft.tudelft.net/MediasiteDeliver/mp4/6775a61b-03df-418b-8fe0-f133cd90385c.mp4?playbackTicket=e73f25ff601744819e34ef88a167b4fd&site=collegerama.tudelft.nl
DASH manifest (the 2nd one with the shortest url):
xidel -s collegerama_585a43626e544bdd97aeb71a0ec907a01d.json -e "$json/d/Presentation/(Streams)()[StreamType=0]/(VideoUrls)()[MimeType='video/x-mpeg-dash'][2]/Location"
https://collegerama-vs-ondemand-delft.tudelft.net/MediasiteDeliver/mp4/6775a61b-03df-418b-8fe0-f133cd90385c.mp4/manifest(format=mpd-isoff,segmentLength=6)?playbackTicket=e73f25ff601744819e34ef88a167b4fd&site=collegerama.tudelft.nl
HLS manifest (the 2nd one with the shortest url):
xidel -s collegerama_585a43626e544bdd97aeb71a0ec907a01d.json -e "$json/d/Presentation/(Streams)()[StreamType=0]/(VideoUrls)()[MimeType='audio/x-mpegurl'][2]/Location"
https://collegerama-vs-ondemand-delft.tudelft.net/MediasiteDeliver/mp4/6775a61b-03df-418b-8fe0-f133cd90385c.mp4/manifest(format=m3u8-aapl-isoff,segmentLength=6)?playbackTicket=e73f25ff601744819e34ef88a167b4fd&site=collegerama.tudelft.nl
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Download with Xidel (only works for [MimeType='video/mp4']):
xidel collegerama_585a43626e544bdd97aeb71a0ec907a01d.json -f "$json/d/Presentation/(Streams)()[StreamType=0]/(VideoUrls)()[MimeType='video/mp4']/Location" --download .
or
xidel collegerama_585a43626e544bdd97aeb71a0ec907a01d.json -e "x:request({'url':$json/d/Presentation/(Streams)()[StreamType=0]/(VideoUrls)()[MimeType='video/mp4']/Location})/file:write-binary(extract(url,'[\da-z-]+\.mp4'),string-to-base64Binary(raw))"
This downloads '6775a61b-03df-418b-8fe0-f133cd90385c.mp4' to the current dir.
Download with FFmpeg:
FOR /F "delims=" %A IN ('xidel -s collegerama_585a43626e544bdd97aeb71a0ec907a01d.json -e "$json/d/Presentation/(Streams)()[StreamType=0]/(VideoUrls)()[MimeType='video/mp4']/Location"') DO ffmpeg -i "%A" -c copy 6775a61b-03df-418b-8fe0-f133cd90385c.mp4
------------------------------------------------------------------------------------------------
[Parse JSON and download slides]
xidel -s collegerama_585a43626e544bdd97aeb71a0ec907a01d.json -e "$json/d/Presentation/(Streams)()[StreamType=2]/(Slides)()/format-integer(Number,'0000')"
0001
0002
0003
[...]
0054
xidel -s collegerama_585a43626e544bdd97aeb71a0ec907a01d.json -e "$json/d/Presentation/(Streams)()[StreamType=2]/(let $path:=SlideBaseUrl return (Slides)()/x'{$path}slide_{format-integer(Number,'0000')}.jpg')"
https://collegerama.tudelft.nl/Mediasite/FileServer/d91dca0351ea4d579f07d9627b59a55c29/Presentation/585a43626e544bdd97aeb71a0ec907a01d/slide_0001.jpg
https://collegerama.tudelft.nl/Mediasite/FileServer/d91dca0351ea4d579f07d9627b59a55c29/Presentation/585a43626e544bdd97aeb71a0ec907a01d/slide_0002.jpg
https://collegerama.tudelft.nl/Mediasite/FileServer/d91dca0351ea4d579f07d9627b59a55c29/Presentation/585a43626e544bdd97aeb71a0ec907a01d/slide_0003.jpg
[...]
https://collegerama.tudelft.nl/Mediasite/FileServer/d91dca0351ea4d579f07d9627b59a55c29/Presentation/585a43626e544bdd97aeb71a0ec907a01d/slide_0054.jpg
xidel -s collegerama_585a43626e544bdd97aeb71a0ec907a01d.json -f "$json/d/Presentation/(Streams)()[StreamType=2]/(let $path:=SlideBaseUrl return (Slides)()/x'{$path}slide_{format-integer(Number,'0000')}.jpg')" --download .
This downloads 'slide_00{01-54}.jpg' to the current dir.
Use --download "{'585a43626e544bdd97aeb71a0ec907a01d\.'}" or --download '585a43626e544bdd97aeb71a0ec907a01d\.' to download them in a sub-directory.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Download progressive mp4 together with the slides:
xidel -s collegerama_585a43626e544bdd97aeb71a0ec907a01d.json -e "let $json:=$json/d/Presentation/(Streams)(),$slide_path:=$json[StreamType=2]/SlideBaseUrl return ($json[StreamType=0]/(VideoUrls)()[MimeType='video/mp4']/Location,$json[StreamType=2]/(Slides)()/x'{$slide_path}slide_{format-integer(Number,'0000')}.jpg')"
https://collegerama-vs-ondemand-delft.tudelft.net/MediasiteDeliver/mp4/6775a61b-03df-418b-8fe0-f133cd90385c.mp4?playbackTicket=e73f25ff601744819e34ef88a167b4fd&site=collegerama.tudelft.nl
https://collegerama.tudelft.nl/Mediasite/FileServer/d91dca0351ea4d579f07d9627b59a55c29/Presentation/585a43626e544bdd97aeb71a0ec907a01d/slide_0001.jpg
https://collegerama.tudelft.nl/Mediasite/FileServer/d91dca0351ea4d579f07d9627b59a55c29/Presentation/585a43626e544bdd97aeb71a0ec907a01d/slide_0002.jpg
https://collegerama.tudelft.nl/Mediasite/FileServer/d91dca0351ea4d579f07d9627b59a55c29/Presentation/585a43626e544bdd97aeb71a0ec907a01d/slide_0003.jpg
[...]
https://collegerama.tudelft.nl/Mediasite/FileServer/d91dca0351ea4d579f07d9627b59a55c29/Presentation/585a43626e544bdd97aeb71a0ec907a01d/slide_0054.jpg
xidel -s collegerama_585a43626e544bdd97aeb71a0ec907a01d.json -e "let $json:=$json/d/Presentation/(Streams)(),$slide_path:=$json[StreamType=2]/SlideBaseUrl return ($json[StreamType=0]/(VideoUrls)()[MimeType='video/mp4']/Location,$json[StreamType=2]/(Slides)()/x'{$slide_path}slide_{format-integer(Number,'0000')}.jpg') ! request-decode(.)/extract((path,url)[1],'.+/(.+)',1)"
6775a61b-03df-418b-8fe0-f133cd90385c.mp4
slide_0001.jpg
slide_0002.jpg
slide_0003.jpg
[...]
slide_0054.jpg
xidel -s collegerama_585a43626e544bdd97aeb71a0ec907a01d.json -f "let $json:=$json/d/Presentation/(Streams)(),$slide_path:=$json[StreamType=2]/SlideBaseUrl return ($json[StreamType=0]/(VideoUrls)()[MimeType='video/mp4']/Location,$json[StreamType=2]/(Slides)()/x'{$slide_path}slide_{format-integer(Number,'0000')}.jpg')" --download "{request-decode($url)/extract((path,url)[1],'.+/(.+)',1)}"
------------------------------------------------------------------------------------------------
[Parse JSON and build FFmpeg command to create a slide-video as a 2nd video-stream]
xidel -s --xquery "'ffmpeg.exe -hide_banner -i "6775a61b-03df-418b-8fe0-f133cd90385c.mp4"'"
ffmpeg.exe -hide_banner -i "6775a61b-03df-418b-8fe0-f133cd90385c.mp4"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
xidel -s collegerama_585a43626e544bdd97aeb71a0ec907a01d.json --xquery "$json/d/Presentation/(Streams)()[StreamType=2]/string-join((Slides)()/x' -loop 1 -i "slide_{format-integer(Number,'0000')}.jpg"')"
-loop 1 -i "slide_0001.jpg" -loop 1 -i "slide_0002.jpg" -loop 1 -i "slide_0003.jpg" [...] -loop 1 -i "slide_0053.jpg" -loop 1 -i "slide_0054.jpg"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
xidel -s collegerama_585a43626e544bdd97aeb71a0ec907a01d.json -e "$json/d/Presentation/(Streams)()[StreamType=2]/(Slides)()/(Time div 1000)"
0.885
88.186
236.687
[...]
5013.31 # Timestamp in seconds at which a slide starts.
xidel -s collegerama_585a43626e544bdd97aeb71a0ec907a01d.json -e "$json/d/Presentation/(Streams)()[StreamType=2]/(for $x in 2 to count((Slides)()) - 1 return ((Slides)($x)/Time - (Slides)($x - 1)/Time) div 1000)"
87.301
148.501
152.502
[...]
41.5 # Duration in seconds of slide 2 to 53.
xidel -s collegerama_585a43626e544bdd97aeb71a0ec907a01d.json -e "let $dur:=$json/d/Presentation/Duration return $json/d/Presentation/(Streams)()[StreamType=2]/(format-number((Slides)(1)/Time div 1000,'9.999'),for $x in 2 to count((Slides)()) - 1 return format-number(((Slides)($x)/Time - (Slides)($x - 1)/Time) div 1000,'9.999'),format-number(($dur - (Slides)()[last()]/Time) div 1000,'9.999'))"
0.885 # Duration in seconds of slide 1.
87.301
148.501
152.502
[...]
41.500 # Duration in seconds (with 3 decimals) of slide 2 to 53.
2699.778 # Duration in seconds of slide 54 (until the end of the lecture video).
xidel -s collegerama_585a43626e544bdd97aeb71a0ec907a01d.json -e "let $dur:=$json/d/Presentation/Duration return $json/d/Presentation/(Streams)()[StreamType=2]/(x'[1:v]trim=duration={format-number((Slides)(1)/Time div 1000,'9.999')}[img1];',for $x in 2 to count((Slides)()) - 1 return x'[{$x}:v]trim=duration={format-number(((Slides)($x)/Time - (Slides)($x - 1)/Time) div 1000,'9.999')}[img{$x}];',x'[{count((Slides)())}:v]trim=duration={format-number(($dur - (Slides)()[last()]/Time) div 1000,'9.999')}[img{count((Slides)())}];')"
[1:v]trim=duration=0.885[img1];
[2:v]trim=duration=87.301[img2];
[3:v]trim=duration=148.501[img3];
[...]
[53:v]trim=duration=41.500[img53];
[54:v]trim=duration=2699.778[img54];
xidel -s collegerama_585a43626e544bdd97aeb71a0ec907a01d.json --xquery "let $dur:=$json/d/Presentation/Duration return $json/d/Presentation/(Streams)()[StreamType=2]/string-join((' -lavfi "',x'[1:v]trim=duration={format-number((Slides)(1)/Time div 1000,'9.999')}[img1];',for $x in 2 to count((Slides)()) - 1 return x'[{$x}:v]trim=duration={format-number(((Slides)($x)/Time - (Slides)($x - 1)/Time) div 1000,'9.999')}[img{$x}];',x'[{count((Slides)())}:v]trim=duration={format-number(($dur - (Slides)()[last()]/Time) div 1000,'9.999')}[img{count((Slides)())}];'))"
-lavfi "[1:v]trim=duration=0.885[img1];[2:v]trim=duration=87.301[img2];[3:v]trim=duration=148.501[img3];[...][53:v]trim=duration=41.500[img53];[54:v]trim=duration=2699.778[img54];
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
xidel -s collegerama_585a43626e544bdd97aeb71a0ec907a01d.json -e "$json/d/Presentation/(Streams)()[StreamType=2]/((Slides)()/x'[img{Number}]'||x'concat=n={count((Slides)())},')"
[img1][img2][img3][...][img53][img54]concat=n=54,
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
xidel -s --xquery "'crop=1454:818:224:27,scale=w=640:h=360:flags=spline,setsar=1,fps=25,format=yuv420p[slides]" -map 0 -map [slides] -c copy -c:v:1 libx264 -preset slower -tune stillimage -metadata:s language=dut 6775a61b-03df-418b-8fe0-f133cd90385c_slides.mp4'"
crop=1454:818:224:27,scale=w=640:h=360:flags=spline,setsar=1,fps=25,format=yuv420p[slides]" -map 0 -map [slides] -c copy -c:v:1 libx264 -preset slower -tune stillimage -metadata:s language=dut 6775a61b-03df-418b-8fe0-f133cd90385c_slides.mp4
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
All combined:
xidel -s collegerama_585a43626e544bdd97aeb71a0ec907a01d.json --xquery "let $dur:=$json/d/Presentation/Duration return $json/d/Presentation/(Streams)()[StreamType=2]/string-join(('ffmpeg.exe -hide_banner -i "6775a61b-03df-418b-8fe0-f133cd90385c.mp4"',(Slides)()/x' -loop 1 -i "slide_{format-integer(Number,'0000')}.jpg"',' -lavfi "',x'[1:v]trim=duration={format-number((Slides)(1)/Time div 1000,'9.999')}[img1];',for $x in 2 to count((Slides)()) - 1 return x'[{$x}:v]trim=duration={format-number(((Slides)($x)/Time - (Slides)($x - 1)/Time) div 1000,'9.999')}[img{$x}];',x'[{count((Slides)())}:v]trim=duration={format-number(($dur - (Slides)()[last()]/Time) div 1000,'9.999')}[img{count((Slides)())}];',(Slides)()/x'[img{Number}]'||x'concat=n={count((Slides)())},','crop=1454:818:224:27,scale=w=640:h=360:flags=spline,setsar=1,fps=25,format=yuv420p[slides]" -map 0 -map [slides] -c copy -c:v:1 libx264 -preset slower -tune stillimage -metadata:slanguage=dut 6775a61b-03df-418b-8fe0-f133cd90385c_slides.mp4'))"
ffmpeg.exe -hide_banner -i "6775a61b-03df-418b-8fe0-f133cd90385c.mp4" -loop 1 -i "slide_0001.jpg" -loop 1 -i "slide_0002.jpg" -loop 1 -i "slide_0003.jpg" -loop 1 -i "slide_0004.jpg" -loop 1 -i "slide_0005.jpg" -loop 1 -i "slide_0006.jpg" -loop 1 -i "slide_0007.jpg" -loop 1 -i "slide_0008.jpg" -loop 1 -i "slide_0009.jpg" -loop 1 -i "slide_0010.jpg" -loop 1 -i "slide_0011.jpg" -loop 1 -i "slide_0012.jpg" -loop 1 -i "slide_0013.jpg" -loop 1 -i "slide_0014.jpg" -loop 1 -i "slide_0015.jpg" -loop 1 -i "slide_0016.jpg" -loop 1 -i "slide_0017.jpg" -loop 1 -i "slide_0018.jpg" -loop 1 -i "slide_0019.jpg" -loop 1 -i "slide_0020.jpg" -loop 1 -i "slide_0021.jpg" -loop 1 -i "slide_0022.jpg" -loop 1 -i "slide_0023.jpg" -loop 1 -i "slide_0024.jpg" -loop 1 -i "slide_0025.jpg" -loop 1 -i "slide_0026.jpg" -loop 1 -i "slide_0027.jpg" -loop 1 -i "slide_0028.jpg" -loop 1 -i "slide_0029.jpg" -loop 1 -i "slide_0030.jpg" -loop 1 -i "slide_0031.jpg" -loop 1 -i "slide_0032.jpg" -loop 1 -i "slide_0033.jpg" -loop 1 -i "slide_0034.jpg" -loop 1 -i "slide_0035.jpg" -loop 1 -i "slide_0036.jpg" -loop 1 -i "slide_0037.jpg" -loop 1 -i "slide_0038.jpg" -loop 1 -i "slide_0039.jpg" -loop 1 -i "slide_0040.jpg" -loop 1 -i "slide_0041.jpg" -loop 1 -i "slide_0042.jpg" -loop 1 -i "slide_0043.jpg" -loop 1 -i "slide_0044.jpg" -loop 1 -i "slide_0045.jpg" -loop 1 -i "slide_0046.jpg" -loop 1 -i "slide_0047.jpg" -loop 1 -i "slide_0048.jpg" -loop 1 -i "slide_0049.jpg" -loop 1 -i "slide_0050.jpg" -loop 1 -i "slide_0051.jpg" -loop 1 -i "slide_0052.jpg" -loop 1 -i "slide_0053.jpg" -loop 1 -i "slide_0054.jpg" -lavfi "[1:v]trim=duration=0.885[img1];[2:v]trim=duration=87.301[img2];[3:v]trim=duration=148.501[img3];[4:v]trim=duration=152.502[img4];[5:v]trim=duration=78.501[img5];[6:v]trim=duration=34.500[img6];[7:v]trim=duration=64.001[img7];[8:v]trim=duration=28.001[img8];[9:v]trim=duration=56.500[img9];[10:v]trim=duration=75.501[img10];[11:v]trim=duration=23.501[img11];[12:v]trim=duration=20.000[img12];[13:v]trim=duration=5.500[img13];[14:v]trim=duration=22.999[img14];[15:v]trim=duration=21.001[img15];[16:v]trim=duration=14.000[img16];[17:v]trim=duration=21.001[img17];[18:v]trim=duration=6.500[img18];[19:v]trim=duration=162.001[img19];[20:v]trim=duration=59.501[img20];[21:v]trim=duration=217.769[img21];[22:v]trim=duration=8.501[img22];[23:v]trim=duration=69.501[img23];[24:v]trim=duration=135.500[img24];[25:v]trim=duration=76.502[img25];[26:v]trim=duration=86.501[img26];[27:v]trim=duration=125.501[img27];[28:v]trim=duration=447.272[img28];[29:v]trim=duration=100.501[img29];[30:v]trim=duration=13.001[img30];[31:v]trim=duration=69.500[img31];[32:v]trim=duration=467.006[img32];[33:v]trim=duration=38.000[img33];[34:v]trim=duration=211.503[img34];[35:v]trim=duration=36.500[img35];[36:v]trim=duration=279.270[img36];[37:v]trim=duration=23.000[img37];[38:v]trim=duration=193.502[img38];[39:v]trim=duration=15.001[img39];[40:v]trim=duration=110.501[img40];[41:v]trim=duration=3.500[img41];[42:v]trim=duration=130.001[img42];[43:v]trim=duration=54.001[img43];[44:v]trim=duration=62.501[img44];[45:v]trim=duration=438.272[img45];[46:v]trim=duration=113.501[img46];[47:v]trim=duration=2.500[img47];[48:v]trim=duration=10.000[img48];[49:v]trim=duration=9.501[img49];[50:v]trim=duration=68.501[img50];[51:v]trim=duration=39.500[img51];[52:v]trim=duration=21.500[img52];[53:v]trim=duration=41.500[img53];[54:v]trim=duration=2699.778[img54];[img1][img2][img3][img4][img5][img6][img7][img8][img9][img10][img11][img12][img13][img14][img15][img16][img17][img18][img19][img20][img21][img22][img23][img24][img25][img26][img27][img28][img29][img30][img31][img32][img33][img34][img35][img36][img37][img38][img39][img40][img41][img42][img43][img44][img45][img46][img47][img48][img49][img50][img51][img52][img53][img54]concat=n=54,crop=1454:818:224:27,scale=w=640:h=360:flags=spline,setsar=1,fps=25,format=yuv420p[slides]" -map 0 -map [slides] -c copy -c:v:1 libx264 -preset slower -tune stillimage -metadata:s language=dut 6775a61b-03df-418b-8fe0-f133cd90385c_slides.mp4
Execute:
FOR /F "delims=" %A IN ('xidel -s collegerama_585a43626e544bdd97aeb71a0ec907a01d.json --xquery "let $dur:=$json/d/Presentation/Duration return $json/d/Presentation/(Streams)()[StreamType=2]/string-join(('ffmpeg.exe -hide_banner -i "6775a61b-03df-418b-8fe0-f133cd90385c.mp4"',(Slides)()/x' -loop 1 -i "slide_{format-integer(Number,'0000')}.jpg"',' -lavfi "',x'[1:v]trim=duration={format-number((Slides)(1)/Time div 1000,'9.999')}[img1];',for $x in 2 to count((Slides)()) - 1 return x'[{$x}:v]trim=duration={format-number(((Slides)($x)/Time - (Slides)($x - 1)/Time) div 1000,'9.999')}[img{$x}];',x'[{count((Slides)())}:v]trim=duration={format-number(($dur - (Slides)()[last()]/Time) div 1000,'9.999')}[img{count((Slides)())}];',(Slides)()/x'[img{Number}]'||x'concat=n={count((Slides)())},','crop=1454:818:224:27,scale=w=640:h=360:flags=spline,setsar=1,fps=25,format=yuv420p[slides]" -map 0 -map [slides] -c copy -c:v:1 libx264 -preset slower -tune stillimage -metadata:slanguage=dut 6775a61b-03df-418b-8fe0-f133cd90385c_slides.mp4'))"') DO %A
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment