handleM3u8 static method

Future<bool> handleM3u8(
  1. Uri uri,
  2. IOStreamedResponse remoteResponse,
  3. HttpResponse response,
  4. VideoCacheServer server,
  5. String? owner,
)

Intercept and proxy m3u8 content.

Implementation

static Future<bool> handleM3u8(Uri uri, IOStreamedResponse remoteResponse, HttpResponse response, VideoCacheServer server, String? owner) async {
  if (isM3u8(remoteResponse.headers['content-type']?.toLowerCase(), uri)) {
    // For a m3u8 request, download and change the URIs in it to proxied version
    String m3u8Content;
    if (remoteResponse.headers['content-encoding'] == 'gzip') {
      response.headers.remove('content-encoding', 'gzip');
      m3u8Content = await http.ByteStream(remoteResponse.stream.cast<List<int>>().transform(gzip.decoder)).bytesToString();
    } else {
      m3u8Content = await remoteResponse.stream.bytesToString();
    }
    Map<String, String>? ownerQuery = owner == null ? null : {'__owner__': owner};
    M3u8 m3u8 = proxyM3u8Content(m3u8Content, (url) => server.getProxyUrl(url, ownerQuery), remoteResponse.requestUri);

    // print('-- M3U8:\n${m3u8.proxied}');
    List<int> bytes = utf8.encode(m3u8.proxied!);
    response.contentLength = bytes.length;
    if (remoteResponse.statusCode == 206) {
      response.headers.set('content-range', 'bytes 0-${bytes.length - 1}/${bytes.length}');
    }
    response.add(bytes);
    await response.flush();
    await response.close();
    return true;
  }
  return false;
}