warren-bank / HLS-Proxy

Node.js server to proxy HLS video streams

Home Page:http://webcast-reloaded.surge.sh/proxy.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

View Proxy Requests

bhanna98 opened this issue · comments

When I am using the proxy to load a m3u8 playlist, my end client ends with a blank screen. Is there a way to view the requests & responses from the http server that hls-proxy runs on to see what the requests & response codes look like in real time? I have charles/burp but clearly do not get the requests being made from the http server itself.

This blank screen is only happening on a certain stream. Others come through without issue. Thanks!

Hi. Using -v 1 or higher, this will print the URL of every request being made by the proxy to the video server. If the response status code isn't in the 200-300 range, then this will print the response. If the response is successful, then you're correct.. there isn't currently any log statement to print the full content. If the request is for a video segment, then the response is piped to the socket.. and it wouldn't make any sense to read from the stream anyway. If, however, the request is for a m3u8 manifest.. then yes, I'd agree that it should be possible to see the full m3u8 content (both the original value as received from the server, as well as the modified value after the URLs have been rewritten to be directed through the proxy). I'll add 2x additional log statements to do this.. that will require a higher verbosity level (ie: -v 4) to be enabled. Would this satisfy your needs?

update: v0.20.2 adds these log statements, which are displayed when using -v 4 or higher.

thank you!

@warren-bank Updated but still having issues. I think I have it pinpointed but not sure if I am right or not with my theory. Are you on discord or any platform to discuss my current issue?

Sorry, no.. I'm not on any social/chat sites.. I'm fairly anti-social, but if you'd like to post the URL for a manifest that isn't proxying well.. I'll give it a quick look and identify the issue.

As it turns I don't think it is an issue with the manifest.. I have been overlooking the fact that it is encrypted with Sample-AES encryption. If you still want to look, I can paste it in here

@warren-bank This is the url FWIW dcs-live-uc1.mp.lura.live/server/play/m10rvaXGcos8a0gx/rendition.m3u8?track=video-3&anvsid=m177626904-nae80564d887cda81645dfbafb7b9bbdf&ts=1667246194

observations..

  • the unproxied manifest includes the encryption key:
      #EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://64899139cb88843cbf786be10915bdfd",KEYFORMAT="com.apple.streamingkeydelivery",KEYFORMATVERSIONS="1"
    
    • please correct me if I'm wrong, but I believe this is Apple FairPlay DRM
    • if so.. then you'll need to play the manifest in a video player that supports this type of encryption
  • the proxied manifest incorrectly modifies this line to:
      #EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://64899139cb88843cbf786be10915bdfd",KEYFORMAT="http://192.168.1.100:8080/aHR0cHM6Ly9kY3MtbGl2ZS11YzEubXAubHVyYS5saXZlL3NlcnZlci9wbGF5L20xMHJ2YVhHY29zOGEwZ3gvY29tLmFwcGxlLnN0cmVhbWluZ2tleWRlbGl2ZXJ5.streamingkeydelivery",KEYFORMATVERSIONS="1"
    
    • in URI, the "skd" URI is correctly left intact
    • in KEYFORMAT, the "com.apple.streamingkeydelivery" is incorrectly matched as a relative filename, and is changed to an absolute URI that redirects through the proxy
      • I'll need to fix this..

I'd guess that Safari would be able to play this.. since:

  • it can natively play HLS
  • it's made by Apple.. so I'd assume that it would support Apple DRM

but.. I don't know for certain;
the only way to know for sure is to try playing the unproxied manifest URL and see what happens.
If the unproxied manifest can play, then the proxied manifest (after I've fixed the above issue) should also play.

@warren-bank I just put it in my iPhone and it played an Ad that was currently live in the player on my test device. See the pasted manifest & headers below. What I can assume from this is that it played the "targeting" .ts video fine because that did not have DRM (see key value is also now set to "none"). Once it kicked back into the content delivered from the 0300801-mp-lura-live.ctl domain was when I got a black screen.

HTTP/1.1 200 OK
Server: nginx
Date: Mon, 31 Oct 2022 22:50:39 GMT
Content-Type: application/x-mpegURL
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, PUT, POST, DELETE, HEAD
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: *
Cache-Control: max-age=0, no-cache, no-store
Content-Range:
X-Anv-Ver: ~~
x-akta-zone: projects/21396452285/zones/us-central1-c
x-akta-locator: dcs-live-prod-us-central1-1-p7np.us-central1-c.c.m-600-2.internal
X-Anv-Auth-Status: valid
x-lura-scmod: 1
X-Anvato-Session: session token
x-node-header-x-anvato-session: session token
X-Anvato-StreamId: stream id
X-Anvato-TTS: 72.57, 66.54, 58.53, 50.52, 42.51, 36.51, 31.37, 25.36, 19.39, 13.38, 7.38, 1.37, -4.63, -10.64, -16.61
x-anv-atb: a - 2096000 - 2264000
Content-Encoding: gzip
Vary: Accept-Encoding
Via: 1.1 google
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
Transfer-Encoding: chunked
Connection: keep-alive

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:1678
#EXT-X-DISCONTINUITY-SEQUENCE:111
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-KEY:METHOD=NONE
#EXTINF:8.000,
https://dcs.mp.lura.live/targeting/analytics?stid=m10rvaXGcos8a0gx&act=3pt&tid=9CB3364427934FBFA837F5F9E1F30846&cues=0%3Amid&url=https%3A%2F%2Fdcs-mcdn.mp.lura.live%2Fprod%2Fv18%2Fmedia%2FC6EF730EC751426AABC59061BE74D58B%2F2200000%2Fsegment-3.ts
#EXTINF:6.033,
https://dcs.mp.lura.live/targeting/analytics?stid=m10rvaXGcos8a0gx&act=3pt&tid=9CB3364427934FBFA837F5F9E1F30846&cues=0%3Atq%2C0%3Acom&url=https%3A%2F%2Fdcs-mcdn.mp.lura.live%2Fprod%2Fv18%2Fmedia%2FC6EF730EC751426AABC59061BE74D58B%2F2200000%2Fsegment-4.ts
#EXT-X-DISCONTINUITY
#EXTINF:8.008,
https://dcs.mp.lura.live/targeting/analytics?stid=m10rvaXGcos8a0gx&act=3pt&tid=9CB3364427934FBFA837F5F9E1F30846&cues=1%3Aimp%2C1%3Ast&url=https%3A%2F%2Fdcs-mcdn.mp.lura.live%2Fprod%2Fv18%2Fmedia%2FD8023B0EF62F4C088A682FC2E896DF44%2F2200000%2Fsegment-1.ts
#EXTINF:8.008,
https://dcs.mp.lura.live/targeting/analytics?stid=m10rvaXGcos8a0gx&act=3pt&tid=9CB3364427934FBFA837F5F9E1F30846&cues=1%3Afq&url=https%3A%2F%2Fdcs-mcdn.mp.lura.live%2Fprod%2Fv18%2Fmedia%2FD8023B0EF62F4C088A682FC2E896DF44%2F2200000%2Fsegment-2.ts
#EXTINF:8.008,
https://dcs.mp.lura.live/targeting/analytics?stid=m10rvaXGcos8a0gx&act=3pt&tid=9CB3364427934FBFA837F5F9E1F30846&cues=1%3Amid&url=https%3A%2F%2Fdcs-mcdn.mp.lura.live%2Fprod%2Fv18%2Fmedia%2FD8023B0EF62F4C088A682FC2E896DF44%2F2200000%2Fsegment-3.ts
#EXTINF:6.006,
https://dcs.mp.lura.live/targeting/analytics?stid=m10rvaXGcos8a0gx&act=3pt&tid=9CB3364427934FBFA837F5F9E1F30846&cues=1%3Atq%2C1%3Acom&url=https%3A%2F%2Fdcs-mcdn.mp.lura.live%2Fprod%2Fv18%2Fmedia%2FD8023B0EF62F4C088A682FC2E896DF44%2F2200000%2Fsegment-4.ts
#EXT-X-DISCONTINUITY
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://64899139cb88843cbf786be10915bdfd",KEYFORMAT="com.apple.streamingkeydelivery",KEYFORMATVERSIONS="1"
#ANVATO-SEGMENT-INFO: type=master
#EXTINF:5.139,
https://o300801-mp-lura-live.ctl.redacted.com/live/ephemeral/54AVmb0klx0KCyCYkFbJwmEle6YKX2NE/nfln-la3/2096k/C1iAPLFPDLQ/169221/segment_169221492.ts?nva=1667260207&token=07a5d82a84f2828510a2e
#ANVATO-SEGMENT-INFO: type=master
#EXTINF:6.006,
https://o300801-mp-lura-live.ctl.redacted.com/live/ephemeral/54AVmb0klx0KCyCYkFbJwmEle6YKX2NE/nfln-la3/2096k/C1iAPLFPDLQ/169221/segment_169221493.ts?nva=1667260213&token=0c4dfa7566abc2b4462b6
#ANVATO-SEGMENT-INFO: type=master
#EXTINF:5.973,
https://o300801-mp-lura-live.ctl.redacted.com/live/ephemeral/54AVmb0klx0KCyCYkFbJwmEle6YKX2NE/nfln-la3/2096k/C1iAPLFPDLQ/169221/segment_169221494.ts?nva=1667260219&token=0100bcd1f5d86aa0fbb17
#ANVATO-SEGMENT-INFO: type=master
#EXTINF:6.006,
https://o300801-mp-lura-live.ctl.redacted.com/live/ephemeral/54AVmb0klx0KCyCYkFbJwmEle6YKX2NE/nfln-la3/2096k/C1iAPLFPDLQ/169221/segment_169221495.ts?nva=1667260225&token=060bfdae60a0b569db46f
#ANVATO-SEGMENT-INFO: type=master
#EXTINF:6.006,
https://o300801-mp-lura-live.ctl.redacted.com/live/ephemeral/54AVmb0klx0KCyCYkFbJwmEle6YKX2NE/nfln-la3/2096k/C1iAPLFPDLQ/169221/segment_169221496.ts?nva=1667260231&token=086911400d5b4660fa1a3
#ANVATO-SEGMENT-INFO: type=master
#EXTINF:6.006,
https://o300801-mp-lura-live.ctl.redacted.com/live/ephemeral/54AVmb0klx0KCyCYkFbJwmEle6YKX2NE/nfln-la3/2096k/C1iAPLFPDLQ/169221/segment_169221497.ts?nva=1667260237&token=0d907bba1313fb99ec073
#ANVATO-NODE:177619163
#ANVATO-SESSION-ID: session token
#ANVATO-CDN-PROVIDER: level3

v0.20.3 is pushed to npm and updates the regex to prevent any change to the KEYFORMAT.

so.. to summarize.. if the manifest uses FairPlay DRM (w/ skd: key URIs), then the info will just pass through the proxy without any changes. If the video player supports FairPlay DRM and knows what to do with this info.. then it should play exactly the same as it would have done without using any proxy.

PS: the structure of that long manifest can be summarized as..

#EXTM3U

#EXT-X-KEY:METHOD=NONE
#EXTINF:45.000,
45sec-of-unencrypted-video-segments.ts

#EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://64899139cb88843cbf786be10915bdfd",KEYFORMAT="com.apple.streamingkeydelivery",KEYFORMATVERSIONS="1"
#EXTINF:5.000,
long-duration-of-encrypted-video-segments.ts

takeaways:

  • it starts with 45 seconds of unencrypted video segments
  • then all subsequent video segments are encrypted

is there a way to include a cookie in the http request? if I wanted to add
hdntl=exp=1667527250~acl=%2f*~data=hdntl~hmac=96b3c088fe1fbfd288a27f876bab996670ea146bfd6eee8ca79ed066aca834e0 this cookie what would the format look like?

yes, but not on a per-manifest basis.. the cookie would be sent with all outbound requests:

hlsd --header "Cookie: name=value; name2=value2; name3=value3"

update: I thought it would be a good idea to support adding request headers (or more generally.. request options) that are conditional on the URL being requested.. so I just released v0.21.0 which adds 2x new hooks.

The readme includes a description, but here's a super fast example:

// hooks.js
module.exports = {
  add_request_options: (url, is_m3u8) => ({headers: {
    "x-abc": "foo"
  }}),

  add_request_headers: (url, is_m3u8) => ({
    "x-xyz": "bar"
  })
}

Of course, these functions aren't applying any conditional logic.. but you can see how easy it would be to do so.

Falsy return values are ignored.

For the purpose of adding headers, only add_request_headers is needed;
add_request_options allows the ability to tweak more of the request behavior, including headers..
I only included it in the example to illustrate usage.

Is it possible instead of a header flag to append every URL request with my cookie? I have not been able to get it functioning yet when using the header to set the cookie. The host requires that hmac cookie when requesting the master.m3u8 file AND when requesting the .ts segments. I realized after some testing that I could append the value at the end of the url like so...

http://some.host.com/hls/#/#/#/master.m3u8?hdntl=exp=1667601490~acl=%2f*~data=hdntl~hmac=cd6a3355902f727bed499565caa7e0564c97ea6b8456adc498e7653258397532

or

http://some.host.com/hls/#/#/#/master_2692_xxxxxxxxx.ts?hdntl=exp=1667601490~acl=%2f*~data=hdntl~hmac=cd6a3355902f727bed499565caa7e0564c97ea6b8456adc498e7653258397532

... and it would give me access to the requested endpoint

well.. if we're no-longer talking about adding conditional headers.. but rather, we now want to add conditional querystring parameters to URLs.. you could use the "redirect" hook:

// hooks.js
module.exports = {
  redirect: (url) => {
    if (url.toLowerCase().indexOf('://some.host.com/') >= 0) {
      const querystring = 'hdntl=exp=1667601490~acl=%2f*~data=hdntl~hmac=cd6a3355902f727bed499565caa7e0564c97ea6b8456adc498e7653258397532'

      url += (url.indexOf('?') >= 0) ? '&' : '?'
      url += querystring
    }
    return url
  }
}

I should note that the value of querystring in the above example doesn't appear to be formatted properly.. but if that's what your backend likes.. then so be it..

In reference to a separate site from above...

#EXTINF:6.006000,no-desc Fragments(video=2477251416062000,format=m3u8-aapl-v3,audiotrack=audio) #EXTINF:6.006000,no-desc Fragments(video=2477251476122000,format=m3u8-aapl-v3,audiotrack=audio) #EXTINF:6.006000,no-desc Fragments(video=2477251536182000,format=m3u8-aapl-v3,audiotrack=audio) #EXTINF:6.006000,no-desc Fragments(video=2477251596242000,format=m3u8-aapl-v3,audiotrack=audio) #EXTINF:6.006000,no-desc Fragments(video=2477251656302000,format=m3u8-aapl-v3,audiotrack=audio) #EXTINF:6.006000,no-desc Fragments(video=2477251716362000,format=m3u8-aapl-v3,audiotrack=audio) #EXTINF:6.006000,no-desc Fragments(video=2477251776422000,format=m3u8-aapl-v3,audiotrack=audio) #EXTINF:6.006000,no-desc Fragments(video=2477251836482000,format=m3u8-aapl-v3,audiotrack=audio) #EXTINF:6.006000,no-desc Fragments(video=2477251896542000,format=m3u8-aapl-v3,audiotrack=audio) #EXTINF:6.006000,no-desc Fragments(video=2477251956602000,format=m3u8-aapl-v3,audiotrack=audio) #EXTINF:6.006000,no-desc Fragments(video=2477252016662000,format=m3u8-aapl-v3,audiotrack=audio) #EXTINF:6.006000,no-desc Fragments(video=2477252076722000,format=m3u8-aapl-v3,audiotrack=audio)

That is a snip from a manifest.m3u8 file. The fragments are constantly concatinated to the file rather than reloading a new set each time. Is there a method for hls proxy to recognize that and keep a base url but add that to it?

that format doesn't look familiar to me..
are there any URLs to video segments (..which you can directly curl) in that snippet of manifest?

so the video fragment is located at

https://domain.akamaized.net/ch12/c12b13f7-32c3-4280-a71f-23ed88237a2a/c12b13f7-32c3-4280-a71f-23ed88237a2a.ism/exp=1667833586~acl=%2f*~data=hdntl,3cad4b4c-eb4f-4603-bfb1-5e5beba4ea0f~hmac=8e774d06f7edbc645f1ab3c9053f9d563227d04b6c87d63bf3704fa971bb8ca4/QualityLevels(4749952)/Fragments(video=2477252076722000,format=m3u8-aapl-v3,audiotrack=audio)

With a validated hmac in the request, it will respond with the video segment (fragment) as the response. The endpoint which returns that is slightly different at

https://domain.akamaized.net/ch12/c12b13f7-32c3-4280-a71f-23ed88237a2a/c12b13f7-32c3-4280-a71f-23ed88237a2a.ism/exp=1667833586~acl=%2f*~data=hdntl,3cad4b4c-eb4f-4603-bfb1-5e5beba4ea0f~hmac=8e774d06f7edbc645f1ab3b9053f9d563227d04b6c87d63bf3704fa971bb8ca4/QualityLevels(4749952)/Manifest(video,format=m3u8-aapl-v3,audiotrack=audio,filter=hls)

well.. if the video host responds to the request:

wget -O '2477251416062000.ts' 'https://domain.akamaized.net/ch12/c12b13f7-32c3-4280-a71f-23ed88237a2a/c12b13f7-32c3-4280-a71f-23ed88237a2a.ism/exp=1667833586~acl=%2f*~data=hdntl,3cad4b4c-eb4f-4603-bfb1-5e5beba4ea0f~hmac=8e774d06f7edbc645f1ab3c9053f9d563227d04b6c87d63bf3704fa971bb8ca4/QualityLevels(4749952)/Fragments(video=2477251416062000,format=m3u8-aapl-v3,audiotrack=audio)'

with:

HTTP/2 200
Content-Type: video/mp2t
Content-Length: ...

and the .m3u8 uses a relative URL to reference this path:

#EXTINF:6.006000,no-desc
Fragments(video=2477251416062000,format=m3u8-aapl-v3,audiotrack=audio)

then the way that the .m3u8 is (currently) parsed to extract URLs won't match these relative URLs..
since it uses a regex that matches patterns..
and this relative path doesn't look very much like a URL.

the hooks that are (currently) available also can't help in this situation,
because there isn't (yet) any hook that gets to modify the raw manifest content before it gets parsed.

having said that.. it might be a good idea to add one.
maybe something like:

// hooks.js
module.exports = {
  modify_m3u8_content: (m3u8_content, m3u8_url) => {
    const base_url = m3u8_url.replace(/[^\/]*$/, '')
    return m3u8_content.replace(
      /^(Fragments\([^\)]+\))$/mg,
      (m0, m1) => base_url + m1
    )
  }
}

actually.. that still wouldn't solve the problem..
since the regex doesn't allow the filename to include any ',' characters;
otherwise, it would match every comma separated list..
which would be bad

though.. this might work;
assuming the video host doesn't object to the commas being URL encoded:

// hooks.js
module.exports = {
  modify_m3u8_content: (m3u8_content, m3u8_url) => {
    const base_url = m3u8_url.replace(/[^\/]*$/, '')
    return m3u8_content.replace(
      /^(Fragments\([^\)]+\))$/mg,
      (m0, m1) => base_url + m1.replace(/[,]/g, '%2C')
    )
  }
}

test to confirm:

{
  const regexs = {}
  regexs.urls  = new RegExp('(^|(?<!(?:KEYFORMAT=))[\\s\'"])((?:https?:/)?/)?((?:[^\\?#/\\s\'"]*/)+?)?([^\\?#,/\\s\'"]+?)(\\.[^\\?#,/\\.\\s\'"]+(?:[\\?#][^\\s\'"]*)?)?([\\s\'"]|$)', 'img')

  let m3u8_content = `
#EXTINF:6.006000,no-desc
Fragments(video=2477251416062000,format=m3u8-aapl-v3,audiotrack=audio)
`

  const m3u8_url = 'https://domain.akamaized.net/ch12/c12b13f7-32c3-4280-a71f-23ed88237a2a/c12b13f7-32c3-4280-a71f-23ed88237a2a.ism/exp=1667833586~acl=%2f*~data=hdntl,3cad4b4c-eb4f-4603-bfb1-5e5beba4ea0f~hmac=8e774d06f7edbc645f1ab3c9053f9d563227d04b6c87d63bf3704fa971bb8ca4/QualityLevels(4749952)/index.m3u8'

  {
    const base_url = m3u8_url.replace(/[^\/]*$/, '')

    m3u8_content = m3u8_content.replace(
      /^(Fragments\([^\)]+\))$/mg,
      (m0, m1) => base_url + m1.replace(/[,]/g, '%2C')
    )
  }

  m3u8_content.replace(regexs.urls, function(match, head, abs_path, rel_path, file_name, file_ext, tail) {
    console.log(JSON.stringify({match, head, abs_path, rel_path, file_name, file_ext, tail}, null, 2))
  })

  void(0)
}

output:

{
  "match": "\nhttps://domain.akamaized.net/ch12/c12b13f7-32c3-4280-a71f-23ed88237a2a/c12b13f7-32c3-4280-a71f-23ed88237a2a.ism/exp=1667833586~acl=%2f*~data=hdntl,3cad4b4c-eb4f-4603-bfb1-5e5beba4ea0f~hmac=8e774d06f7edbc645f1ab3c9053f9d563227d04b6c87d63bf3704fa971bb8ca4/QualityLevels(4749952)/Fragments(video=2477251416062000%2Cformat=m3u8-aapl-v3%2Caudiotrack=audio)\n",
  "head": "\n",
  "abs_path": "https://",
  "rel_path": "domain.akamaized.net/ch12/c12b13f7-32c3-4280-a71f-23ed88237a2a/c12b13f7-32c3-4280-a71f-23ed88237a2a.ism/exp=1667833586~acl=%2f*~data=hdntl,3cad4b4c-eb4f-4603-bfb1-5e5beba4ea0f~hmac=8e774d06f7edbc645f1ab3c9053f9d563227d04b6c87d63bf3704fa971bb8ca4/QualityLevels(4749952)/",
  "file_name": "Fragments(video=2477251416062000%2Cformat=m3u8-aapl-v3%2Caudiotrack=audio)",
  "tail": "\n"
}

v0.22.0 was just pushed to npm.. and it adds this new hook method.

I tested the examples given earlier.. and they work as expected.

Here is a more complete example, which uses the redirect hook to undo the URL-escaping of commas that occur in the earlier modify_m3u8_content hook.. because they are required during the parsing phase to pattern-match the URLs:

//hooks.js
module.exports = {
  modify_m3u8_content: (m3u8_content, m3u8_url) => {
    const base_url = m3u8_url.replace(/[^\/]*$/, '')
    return m3u8_content.replace(
      /^(Fragments\([^\)]+\))$/mg,
      (m0, m1) => base_url + m1.replace(/[,]/g, '%2C')
    )
  },
  redirect: (url) => {
    return url.replace(
      /^(.+\/)(Fragments\([^\)]+\))$/,
      (m0, m1, m2) => m1 + m2.replace(/%2C/g, ',')
    )
  }
}

So for hook usage in my case - I would create the hooks.js file & then call that with --hooks modify_m3u8_content in the command to start hlsd?

hlsd --hooks '/path/to/hooks.js'

@warren-bank Had to take a break last week but I am getting back to my project here. After doing some digging it looks like the platform originating the stream is utilizing Azure Media Service with Apple HLS v3

https://learn.microsoft.com/en-us/azure/media-services/previous/media-services-deliver-content-overview <-- is a great reference. If you have time could you check that and let me know if hls-proxy would still be suitable for my project with this delivery?

Edit: Also I found out that the Manifest(video,format=m3u8-aapl-v3,audiotrack=audio,filter=hls) url will respond if .m3u8 is appended. Not sure if that helps in any way

@warren-bank you can also find a test endpoint that microsoft hosts here. https://testweb.playready.microsoft.com/Content/Content2X

You can see the first manifest returns the manifest with quality/bandwidth values... https://profficialsite.origin.mediaservices.windows.net/c51358ea-9a5e-4322-8951-897d640fdfd7/tearsofsteel_4k.ism/manifest(format=m3u8-aapl-v3)

That can be bypassed as it can be hardcoded. The next m3u8 file to grab is located at... https://profficialsite.origin.mediaservices.windows.net/c51358ea-9a5e-4322-8951-897d640fdfd7/tearsofsteel_4k.ism/QualityLevels(5820064)/Manifest(video,format=m3u8-aapl-v3,audiotrack=aac_UND_2_128) You can see the base url is appended with the value from the 1st manifest request.

The last request is for a fragment from the
/QualityLevels()/Manifest(video,format=m3u8-aapl-v3,audiotrack=aac_UND_2_128) endpoint. We can see here the first fragment is located at ... https://profficialsite.origin.mediaservices.windows.net/c51358ea-9a5e-4322-8951-897d640fdfd7/tearsofsteel_4k.ism/QualityLevels(5820064)/Fragments(video=0,format=m3u8-aapl-v3,audiotrack=aac_UND_2_128) This fragment is a video/mp2t which is exactly what we need, right?

The difference between this test environment and mine is that the test urls have a defined end of list while the streamed content in the environment I am working with has no predetermined end of list.

@warren-bank Is this still being followed?

Admittedly, I haven't given this issue any thought.

I just did some reading.. on these URLs.. which are produced by videos hosted by Microsoft Azure Media Services..

https://learn.microsoft.com/en-us/azure/media-services/previous/
https://learn.microsoft.com/en-us/azure/media-services/previous/media-services-deliver-content-overview
  Azure Media Services v2

https://learn.microsoft.com/en-us/azure/media-services/latest/
https://learn.microsoft.com/en-us/azure/media-services/latest/encode-dynamic-packaging-concept
https://learn.microsoft.com/en-us/azure/media-services/latest/filters-dynamic-manifest-concept
  Azure Media Services v3

https://azure.microsoft.com/en-us/blog/dynamic-manifest/
https://azure.microsoft.com/en-us/blog/azure-media-services-release-dynamic-manifest-composition-remove-hls-audio-only-track-and-hls-i-frame-track-support/

and inspecting the manifest that you referenced:

https://testweb.playready.microsoft.com/Content/Content2X

http://profficialsite.origin.mediaservices.windows.net/c51358ea-9a5e-4322-8951-897d640fdfd7/tearsofsteel_4k.ism/manifest(format=m3u8-aapl)
  => manifest-master.m3u8
http://profficialsite.origin.mediaservices.windows.net/c51358ea-9a5e-4322-8951-897d640fdfd7/tearsofsteel_4k.ism/QualityLevels(3294017)/Manifest(video,format=m3u8-aapl)
  => manifest-child.m3u8
http://profficialsite.origin.mediaservices.windows.net/c51358ea-9a5e-4322-8951-897d640fdfd7/tearsofsteel_4k.ism/QualityLevels(3294017)/Fragments(video=0,format=m3u8-aapl)
  => segment-001.ts
http://profficialsite.origin.mediaservices.windows.net/c51358ea-9a5e-4322-8951-897d640fdfd7/tearsofsteel_4k.ism/QualityLevels(3294017)/Fragments(video=100000000,format=m3u8-aapl)
  => segment-002.ts

As I see it, I have 2 options:

  1. add a hacky workaround to the existing regex patterns to detect these URL conventions
  2. go back to the drawing board.. and rewrite the m3u8 parser
    • the existing methodology is a naive parser..
      not making any assumptions about the format of the blob of text from which it's extracting URLs
    • a better methodology would be a parser that understands the format of m3u8 manifests..
      and uses context to extract URLs
      • which would allow URLs to be be structured in any way that the video host likes (ex: Azure)
      • which would prevent matching false positives

Option 2 sounds like a good idea. Of course, it could also completely break the app.. if not careful. I'll probably play around with this idea over the next few days.

notes..

https://datatracker.ietf.org/doc/html/rfc8216
  stable spec

manifest URLs:
==============
#EXT-X-MEDIA: ... URI="${URL}"
#EXT-X-I-FRAME-STREAM-INF: ... URI="${URL}"
#EXT-X-STREAM-INF: ... \n${URL}

segment URLs:
=============
#EXTINF: ...\n${URL}

other URLs:
===========
#EXT-X-KEY: ... URI="${URL}"
#EXT-X-SESSION-DATA: ... URI="${URL}"
https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis
  draft spec

manifest URLs:
==============
#EXT-X-MEDIA: ... URI="${URL}"
#EXT-X-I-FRAME-STREAM-INF: ... URI="${URL}"
#EXT-X-RENDITION-REPORT: ... URI="${URL}"
#EXT-X-DATERANGE: ... X-ASSET-URI="${URL}"
#EXT-X-CONTENT-STEERING: ... SERVER-URI="${URL}"
#EXT-X-STREAM-INF: ... \n${URL}

segment URLs:
=============
#EXT-X-PART: ... URI="${URL}"
#EXT-X-PRELOAD-HINT: ... URI="${URL}"
#EXTINF: ...\n${URL}

other URLs:
===========
#EXT-X-KEY: ... URI="${URL}"
#EXT-X-SESSION-DATA: ... URI="${URL}"

I have created a companion script that will actively run in the background along side hls. It's functionality is to get an active session token (hmac) for the endpoints that require them. I haven't implemented database storage at the time for those values but that is the plan. As of right now they are just written to json objects and stored locally.

Feasibly that companion script could be used alongside a hook I guess? To set parts of the url as a variable that requests those values from the local storage? As far as detection goes, the only way I see it possible would be for you to detect ".ism" within the link and use a function dedicated to the azure media services delivery platform

quick update.. I finally gave this repo some attention and did a ton of internal housekeeping, refactoring, and rewriting. I like where it is now.. so unless I'm told that I broke something.. I'll probably leave it alone (at v3.0.0) for now.

regarding the Azure/PlayReady manifests.. the proxy (with its completely new manifest parser) can now successfully detect and encode its URLs. That said, I couldn't easily find a video player that supports PlayReady.. but the stream plays the same for me (ie: artifacts on the screen because the stream is scrambled) when using the proxy as it does when playing the stream directly (in VLC on Win64, and in ExoPlayer on Android). So.. if you have a video player that supports PlayReady.. I'm fairly certain it'll work through the proxy.

https://ampdemo.azureedge.net/ looks to be a good demo site. I will play around with the new update today! Is it the same usage command to start up?

Disregard previous question about usage.

May need a little debugging if this is not an issue solely on my end. If my top level manifest link is

https://amssamples.streaming.mediaservices.windows.net/b6822ec8-5c2b-4ae0-a851-fd46a78294e9/ElephantsDream.ism/manifest(format=m3u8-aapl-v3)

Then the next phase is a bandwidth determination. Since those bandwidth levels are static, could we hardcode that value to say something like --bandwidth 4925887 which would direct us to this from the bandwidth Manifest...

#EXT-X-STREAM-INF:BANDWIDTH=4925887,RESOLUTION=1920x1080,CODECS="avc1.640028,mp4a.40.2" QualityLevels(4678229)/Manifest(video,format=m3u8-aapl-v3,audiotrack=AAC_und_ch2_56kbps)

Which would now make our Fragment manifest...

https://amssamples.streaming.mediaservices.windows.net/b6822ec8-5c2b-4ae0-a851-fd46a78294e9/ElephantsDream.ism/QualityLevels(4678229)/Manifest(video,format=m3u8-aapl-v3,audiotrack=AAC_und_ch2_56kbps)

The proxy in 3.0.0 does fine when it is directly calling a Fragment URL

I.e. https://amssamples.streaming.mediaservices.windows.net/b6822ec8-5c2b-4ae0-a851-fd46a78294e9/ElephantsDream.ism/QualityLevels(4678229)/Fragments(video=600000000,format=m3u8-aapl-v3,audiotrack=AAC_und_ch2_56kbps)

But if I call the full fragment manifest it just returns that manifest rather than parsing those fragments into a fetched stream

the only change to user space is that file extensions appended to the encoded URL are now very important, whereas previously they were optional.
ex: http://localhost:8080/xxxxx.m3u8

previously, the xxxxx was base64 decoded to reveal the origin url.. and assumptions were made.. such as that the url includes a file extension to indicate what type of file is being proxied.
now, the .m3u8 is used to know that the url points to a manifest.
since the proxy always appends an explicit extension to the urls within a manifest that it rewrites.. no assumptions are needed.
however, for a 3rd party to get the ball rolling.. an .m3u8 file extension is now required.

as far as your comment about video "fragments"..
I get the sense that you think the proxy is in some way transcoding the video stream..
and should be merging segments.. which is entirely not the case.
there is no transcoding.. and there never will be.

the manifest is modified so the url to each individual video segment (ie: "fragment") is rewritten to be directed through the proxy (with the original url being base64 encoded and a .ts file extension appended).

and when each video segment is requested through the proxy by a client.. it is retrieved (either by requesting it from the origin server or by obtaining it from the internal cache) and returned in the response.

OK, yes.. that is correct.

Here is a quick example to walk through its behavior using the example (master) manifest:

https://testweb.playready.microsoft.com/Content/Content2X

http://profficialsite.origin.mediaservices.windows.net/c51358ea-9a5e-4322-8951-897d640fdfd7/tearsofsteel_4k.ism/manifest(format=m3u8-aapl)
  => manifest-master.m3u8
http://profficialsite.origin.mediaservices.windows.net/c51358ea-9a5e-4322-8951-897d640fdfd7/tearsofsteel_4k.ism/QualityLevels(3294017)/Manifest(video,format=m3u8-aapl)
  => manifest-child.m3u8
http://profficialsite.origin.mediaservices.windows.net/c51358ea-9a5e-4322-8951-897d640fdfd7/tearsofsteel_4k.ism/QualityLevels(3294017)/Fragments(video=0,format=m3u8-aapl)
  => segment-001.ts
http://profficialsite.origin.mediaservices.windows.net/c51358ea-9a5e-4322-8951-897d640fdfd7/tearsofsteel_4k.ism/QualityLevels(3294017)/Fragments(video=100000000,format=m3u8-aapl)
  => segment-002.ts

The corresponding encoded URLs to proxy these endpoints are:

http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL21hbmlmZXN0KGZvcm1hdD1tM3U4LWFhcGwp.m3u8
  => manifest-master.m3u8
http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvTWFuaWZlc3QodmlkZW8sZm9ybWF0PW0zdTgtYWFwbCk=.m3u8
  => manifest-child.m3u8
http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  => segment-001.ts
http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTEwMDAwMDAwMCxmb3JtYXQ9bTN1OC1hYXBsKQ==.ts
  => segment-002.ts

Where the modified manifests are:

manifest-master.m3u8
  #EXTM3U
  #EXT-X-VERSION:4
  #EXT-X-PLAYREADYHEADER:YAMAAAEAAQBWAzwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ANABSAHAAbABiACsAVABiAE4ARQBTADgAdABHAGsATgBGAFcAVABFAEgAQQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBLAEwAagAzAFEAegBRAFAALwBOAEEAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APABMAEEAXwBVAFIATAA+AGgAdAB0AHAAcwA6AC8ALwBwAHIAbwBmAGYAaQBjAGkAYQBsAHMAaQB0AGUALgBrAGUAeQBkAGUAbABpAHYAZQByAHkALgBtAGUAZABpAGEAcwBlAHIAdgBpAGMAZQBzAC4AdwBpAG4AZABvAHcAcwAuAG4AZQB0AC8AUABsAGEAeQBSAGUAYQBkAHkALwA8AC8ATABBAF8AVQBSAEwAPgA8AEMAVQBTAFQATwBNAEEAVABUAFIASQBCAFUAVABFAFMAPgA8AEkASQBTAF8ARABSAE0AXwBWAEUAUgBTAEkATwBOAD4AOAAuADEALgAyADIAMQAwAC4AMgAyADAAMgA8AC8ASQBJAFMAXwBEAFIATQBfAFYARQBSAFMASQBPAE4APgA8AC8AQwBVAFMAVABPAE0AQQBUAFQAUgBJAEIAVQBUAEUAUwA+ADwALwBEAEEAVABBAD4APAAvAFcAUgBNAEgARQBBAEQARQBSAD4A
  #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",NAME="aac_UND_2_128",DEFAULT=YES,URI="http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMTI4MDAzKS9NYW5pZmVzdChhYWNfVU5EXzJfMTI4LGZvcm1hdD1tM3U4LWFhcGwp.m3u8"
  #EXT-X-STREAM-INF:BANDWIDTH=1138489,RESOLUTION=640x288,CODECS="avc1.640015,mp4a.40.2",AUDIO="audio"
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoOTcwMDEwKS9NYW5pZmVzdCh2aWRlbyxmb3JtYXQ9bTN1OC1hYXBsKQ==.m3u8
  #EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=1138489,RESOLUTION=640x288,CODECS="avc1.640015",URI="http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoOTcwMDEwKS9NYW5pZmVzdCh2aWRlbyxmb3JtYXQ9bTN1OC1hYXBsLHR5cGU9a2V5ZnJhbWVzKQ==.m3u8"
  #EXT-X-STREAM-INF:BANDWIDTH=2376263,RESOLUTION=960x428,CODECS="avc1.64001e,mp4a.40.2",AUDIO="audio"
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMjE4MTEzOSkvTWFuaWZlc3QodmlkZW8sZm9ybWF0PW0zdTgtYWFwbCk=.m3u8
  #EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=2376263,RESOLUTION=960x428,CODECS="avc1.64001e",URI="http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMjE4MTEzOSkvTWFuaWZlc3QodmlkZW8sZm9ybWF0PW0zdTgtYWFwbCx0eXBlPWtleWZyYW1lcyk=.m3u8"
  #EXT-X-STREAM-INF:BANDWIDTH=3513624,RESOLUTION=1280x572,CODECS="avc1.64001f,mp4a.40.2",AUDIO="audio"
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvTWFuaWZlc3QodmlkZW8sZm9ybWF0PW0zdTgtYWFwbCk=.m3u8
  #EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=3513624,RESOLUTION=1280x572,CODECS="avc1.64001f",URI="http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvTWFuaWZlc3QodmlkZW8sZm9ybWF0PW0zdTgtYWFwbCx0eXBlPWtleWZyYW1lcyk=.m3u8"
  #EXT-X-STREAM-INF:BANDWIDTH=4782065,RESOLUTION=1920x860,CODECS="avc1.640028,mp4a.40.2",AUDIO="audio"
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoNDUzNTE1MykvTWFuaWZlc3QodmlkZW8sZm9ybWF0PW0zdTgtYWFwbCk=.m3u8
  #EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=4782065,RESOLUTION=1920x860,CODECS="avc1.640028",URI="http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoNDUzNTE1MykvTWFuaWZlc3QodmlkZW8sZm9ybWF0PW0zdTgtYWFwbCx0eXBlPWtleWZyYW1lcyk=.m3u8"
  #EXT-X-STREAM-INF:BANDWIDTH=6095244,RESOLUTION=1920x860,CODECS="avc1.640028,mp4a.40.2",AUDIO="audio"
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoNTgyMDA2NCkvTWFuaWZlc3QodmlkZW8sZm9ybWF0PW0zdTgtYWFwbCk=.m3u8
  #EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=6095244,RESOLUTION=1920x860,CODECS="avc1.640028",URI="http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoNTgyMDA2NCkvTWFuaWZlc3QodmlkZW8sZm9ybWF0PW0zdTgtYWFwbCx0eXBlPWtleWZyYW1lcyk=.m3u8"
  #EXT-X-STREAM-INF:BANDWIDTH=8096400,RESOLUTION=2560x1144,CODECS="avc1.640032,mp4a.40.2",AUDIO="audio"
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoNzc3ODE0MikvTWFuaWZlc3QodmlkZW8sZm9ybWF0PW0zdTgtYWFwbCk=.m3u8
  #EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=8096400,RESOLUTION=2560x1144,CODECS="avc1.640032",URI="http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoNzc3ODE0MikvTWFuaWZlc3QodmlkZW8sZm9ybWF0PW0zdTgtYWFwbCx0eXBlPWtleWZyYW1lcyk=.m3u8"
  #EXT-X-STREAM-INF:BANDWIDTH=10117885,RESOLUTION=2560x1144,CODECS="avc1.640032,mp4a.40.2",AUDIO="audio"
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoOTc1NjExMikvTWFuaWZlc3QodmlkZW8sZm9ybWF0PW0zdTgtYWFwbCk=.m3u8
  #EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=10117885,RESOLUTION=2560x1144,CODECS="avc1.640032",URI="http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoOTc1NjExMikvTWFuaWZlc3QodmlkZW8sZm9ybWF0PW0zdTgtYWFwbCx0eXBlPWtleWZyYW1lcyk=.m3u8"
  #EXT-X-STREAM-INF:BANDWIDTH=12129814,RESOLUTION=2560x1144,CODECS="avc1.640032,mp4a.40.2",AUDIO="audio"
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMTE3MjQ3MzEpL01hbmlmZXN0KHZpZGVvLGZvcm1hdD1tM3U4LWFhcGwp.m3u8
  #EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=12129814,RESOLUTION=2560x1144,CODECS="avc1.640032",URI="http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMTE3MjQ3MzEpL01hbmlmZXN0KHZpZGVvLGZvcm1hdD1tM3U4LWFhcGwsdHlwZT1rZXlmcmFtZXMp.m3u8"
  #EXT-X-STREAM-INF:BANDWIDTH=14127575,RESOLUTION=3840x1716,CODECS="avc1.640033,mp4a.40.2",AUDIO="audio"
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMTM2Nzk0ODgpL01hbmlmZXN0KHZpZGVvLGZvcm1hdD1tM3U4LWFhcGwp.m3u8
  #EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=14127575,RESOLUTION=3840x1716,CODECS="avc1.640033",URI="http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMTM2Nzk0ODgpL01hbmlmZXN0KHZpZGVvLGZvcm1hdD1tM3U4LWFhcGwsdHlwZT1rZXlmcmFtZXMp.m3u8"
  #EXT-X-STREAM-INF:BANDWIDTH=16130666,RESOLUTION=3840x1716,CODECS="avc1.640033,mp4a.40.2",AUDIO="audio"
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMTU2Mzk0NTkpL01hbmlmZXN0KHZpZGVvLGZvcm1hdD1tM3U4LWFhcGwp.m3u8
  #EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=16130666,RESOLUTION=3840x1716,CODECS="avc1.640033",URI="http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMTU2Mzk0NTkpL01hbmlmZXN0KHZpZGVvLGZvcm1hdD1tM3U4LWFhcGwsdHlwZT1rZXlmcmFtZXMp.m3u8"
  #EXT-X-STREAM-INF:BANDWIDTH=18134680,RESOLUTION=3840x1716,CODECS="avc1.640033,mp4a.40.2",AUDIO="audio"
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMTc2MDAzMzQpL01hbmlmZXN0KHZpZGVvLGZvcm1hdD1tM3U4LWFhcGwp.m3u8
  #EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=18134680,RESOLUTION=3840x1716,CODECS="avc1.640033",URI="http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMTc2MDAzMzQpL01hbmlmZXN0KHZpZGVvLGZvcm1hdD1tM3U4LWFhcGwsdHlwZT1rZXlmcmFtZXMp.m3u8"
  #EXT-X-STREAM-INF:BANDWIDTH=20115909,RESOLUTION=4096x1828,CODECS="avc1.640033,mp4a.40.2",AUDIO="audio"
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMTk1Mzg5MTQpL01hbmlmZXN0KHZpZGVvLGZvcm1hdD1tM3U4LWFhcGwp.m3u8
  #EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=20115909,RESOLUTION=4096x1828,CODECS="avc1.640033",URI="http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMTk1Mzg5MTQpL01hbmlmZXN0KHZpZGVvLGZvcm1hdD1tM3U4LWFhcGwsdHlwZT1rZXlmcmFtZXMp.m3u8"
manifest-child.m3u8
  #EXTM3U
  #EXT-X-VERSION:4
  #EXT-X-PLAYLIST-TYPE:VOD
  #EXT-X-ALLOW-CACHE:NO
  #EXT-X-MEDIA-SEQUENCE:0
  #EXT-X-TARGETDURATION:10
  #EXT-X-PROGRAM-DATE-TIME:1970-01-01T00:00:00Z
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTEwMDAwMDAwMCxmb3JtYXQ9bTN1OC1hYXBsKQ==.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTIwMDAwMDAwMCxmb3JtYXQ9bTN1OC1hYXBsKQ==.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTMwMDAwMDAwMCxmb3JtYXQ9bTN1OC1hYXBsKQ==.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTQwMDAwMDAwMCxmb3JtYXQ9bTN1OC1hYXBsKQ==.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTUwMDAwMDAwMCxmb3JtYXQ9bTN1OC1hYXBsKQ==.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTYwMDAwMDAwMCxmb3JtYXQ9bTN1OC1hYXBsKQ==.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTcwMDAwMDAwMCxmb3JtYXQ9bTN1OC1hYXBsKQ==.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTgwMDAwMDAwMCxmb3JtYXQ9bTN1OC1hYXBsKQ==.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTkwMDAwMDAwMCxmb3JtYXQ9bTN1OC1hYXBsKQ==.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTEwMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTExMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTEyMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTEzMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTE0MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTE1MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTE2MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTE3MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTE4MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTE5MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTIwMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTIxMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTIyMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTIzMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTI0MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTI1MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTI2MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTI3MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTI4MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTI5MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTMwMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTMxMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTMyMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTMzMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTM0MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTM1MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTM2MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTM3MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTM4MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTM5MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTQwMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTQxMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTQyMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTQzMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTQ0MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTQ1MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTQ2MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTQ3MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTQ4MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTQ5MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTUwMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTUxMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTUyMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTUzMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTU0MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTU1MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTU2MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTU3MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTU4MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTU5MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTYwMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTYxMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTYyMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTYzMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTY0MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTY1MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTY2MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTY3MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTY4MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTY5MDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTcwMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTcxMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:10.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTcyMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXTINF:4.000000,no-desc
  http://127.0.0.1:8080/aHR0cDovL3Byb2ZmaWNpYWxzaXRlLm9yaWdpbi5tZWRpYXNlcnZpY2VzLndpbmRvd3MubmV0L2M1MTM1OGVhLTlhNWUtNDMyMi04OTUxLTg5N2Q2NDBmZGZkNy90ZWFyc29mc3RlZWxfNGsuaXNtL1F1YWxpdHlMZXZlbHMoMzI5NDAxNykvRnJhZ21lbnRzKHZpZGVvPTczMDAwMDAwMDAsZm9ybWF0PW0zdTgtYWFwbCk=.ts
  #EXT-X-ENDLIST

well.. actually "yes" and "no".. your example has problems.

this:

https://localhost.com/b6822ec8-5c2b-4ae0-a851-fd46a78294e9/ElephantsDream.ism/QualityLevels(4678229)/Fragments(video=600000000,format=m3u8-aapl-v3,audiotrack=AAC_und_ch2_56kbps)

..is not a valid URL to make a request to the proxy

as the readme describes, the format of a proxied URL is:

  proxy_url='http://127.0.0.1:8080'
  video_url='https://amssamples.streaming.mediaservices.windows.net/b6822ec8-5c2b-4ae0-a851-fd46a78294e9/ElephantsDream.ism/QualityLevels(4678229)/Fragments(video=600000000,format=m3u8-aapl-v3,audiotrack=AAC_und_ch2_56kbps)'
  file_extension='.ts'

  hls_proxy_url="${proxy_url}/"$(echo -n "$video_url" | base64 --wrap=0)"$file_extension"

though, I personally always use this webpage to do all of the hard work for me.
If you pipe the resulting URL to the option for "AirPlay sender",
then the proxied URL will be pre-populated in the text input field: "Video URL".

notes:

  • this webpage assumes that the video URL provided by the user is for a manifest file, and appends the .m3u8 file extension
  • if you're using the webpage as a tool to generate encoded proxy URLs for other types of files,
    you'll need to change the file extension to reflect the actual type of endpoint
    • ex: .m3u8, .ts, .key, .json, .other

I see. I will give it another test run on my end tomorrow. Looks like it was an error on my end as I did not know the file extensions were required as of latest update

Working great! Looks like the website uses user-agent strings as a form of security validation. If I wanted to write a hook to fetch the user agent from a json file, what would that look like in my command usage? and would the hook look like this...

// hooks.js module.exports = { user-agent: require(./useragent.json).UA }

unless you need to configure different user-agent request headers for different video hosts (which is unlikely), you could just configure a global value that is included in all requests:

hlsd --useragent 'Chrome/100' ...

but.. if you really do need to apply logic on a per-request basis, then either of these 2x hooks could be used:

  • add_request_headers
  • add_request_options

..the signatures of each hook is described in the readme