Created
May 14, 2021 16:29
-
-
Save Reino17/4e8d02e1237ab0c77f761fab19d1f3f2 to your computer and use it in GitHub Desktop.
Extract and download videos from Collegerama with Xidel and/or FFmpeg
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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