브라우저의 HARQ를 통해 암호화된 HLS 스트림 저장

15075 단어 streamingHLS
실제로 웹 브라우저의 개발 도구에 대해 HTTP 요청과 응답은 대부분 HARD(HTTP Archive)라고 불린다.json 파일로 저장하는 기능이 있습니다.이것은 매우 편리해서 각양각색의 방법을 응용할 수 있다.
이번에는 흐르는 영상/소리를 HARQ로 저장하여 데이터를 추출합니다.
스크립트in.har에서 키 데이터 추출 및 .m3u8.ts: https://github.com/okuoku/striphls/blob/5c592c735e79f3fc604c5b6da4d8cf3cd66cc664/run.js

할 일


이번 프로젝트는 Amazon Elastic Transcoder와 HLS AES 암호화, HLS가 적용됐다.js 플레이어의 조합을 가정했습니다.세상의 애니메이션 편지 배달 사이트는 일반적으로 더욱 진지한 암호화/전송 방식을 사용하기 때문에 이 방법을 사용할 수 없다.
HLS(HTTP Live Streaming)는 스트리밍 프로토콜 중 하나로 이미 광범위한 클라이언트/서버 지원이 존재하고 모두 HTTP로 완성된 것이 특징이다...또한 웹 브라우저에는 통신 컨텐트를 HARQ 형식으로 내보내는 기능이 있습니다.
  • 개발자 도구 열기(F12)
  • 리셋 버튼 누르기
  • 재생이 끝난 후 HARD로 HTTP 통신 내용을 저장
  • 저장된 HARQ에서 스트림 제거
  • 이렇게 할 수 있다.모두 HTTP로 끝났고 재생에 필요한 것은 모두 HTTP 로그에 기록되어 있습니다.

    HARQ 저장


    HARQ는 개발자 도구에 저장됩니다.

    이 캡처는 Firefox, Chrome, IE 11을 사용합니다.하지만 똑같이 저장할 수 있다.
    Firefox의 경우 기본적으로 HARQ에서 1MiB 이상의 데이터가 생략됩니다.이를 피하기 위해 about:config에서 devtools.netmonitor.responseBodyLimit를 0으로 설정합니다.

    HARQ 액세스


    HARQ는 단순할 뿐이야.json이기 때문에 JSON을 처리할 수 있는 프로그래밍 언어라면 무엇이든 사용할 수 있습니다.이번에는 노멀 노드.js를 사용했습니다.
    const har = JSON.parse(fs.readFileSync(path.resolve(__dirname, "in.har")).toString("utf8"));
    
    그런 다음 forEach로 파일을 Buffer 또는 다른 형식으로 변환합니다.
    const entries = har.log.entries; // ★ ファイルの log.entries にリクエストの一覧がある
    
    const urls = {}; // ★ URLをキーにした辞書
    const files = []; // ★ 全ファイルを含む配列
    
    entries.forEach(e => {
        let entry = false;
        const url = new URL(e.request.url);
        const name = url.pathname;
        const basename = path.basename(url.pathname);
        if(e.response.content.text){
            if(e.response.content.encoding == "base64"){
                entry = new Buffer.from(e.response.content.text, "base64");
            }else{
                entry = e.response.content.text;
            }
        }
        files.push({name: name, ext: path.extname(name), 
                   basename: basename,
                   blob: entry});
        urls[url] = entry;
    });
    

    .m3u8에 포함된 키 URL 처리


    HLS에서는 미디어 파일을 작은 파일로 분할하여 처리합니다.분할된 파일의 URL은 확장자.m3u8 파일에 나열되며 분할 파일을 디코딩하는 키 파일의 URL도 포함됩니다.
    저장된 HARQ에서도 키는 액세스.m3u8 파일에 지정된 키 URL 형식으로 저장되어야 합니다.
  • HARQ에서 찾기.m3u8 파일
  • .m3u8 추출된 파일에 포함된 키 URL
  • HARQ에서 키 URL을 찾아 파일에 저장
  • 저장된 파일을 가리키는 것처럼.m3u8 저장된 파일을 가공
  • 이러한 절차에서는 키를 추출할 수 있고 추출된 키를 사용하여 생성할 수 있다.m3u8.
    // Extract key, modified .m3u8
    files.forEach(e => {
        const reKeyUrl = RegExp('#EXT-X-KEY:METHOD=AES-128,URI="([^"]+)"'); // ★ 鍵URLの検出
        if(e.ext == ".m3u8"){
            if(e.blob instanceof Buffer){
                e.blob = e.blob.toString("utf8");
            }
            const keyUrlArr = reKeyUrl.exec(e.blob);
            if(reKeyUrl.exec(e.blob)){
                const keyUrl = keyUrlArr[1];
                if(urls[keyUrl]){
                    console.log(keyUrl);
                    console.log(urls[keyUrl]);
                    const out = // ★ .m3u8の加工
                        e.blob.replace(reKeyUrl, "#EXT-X-KEY:METHOD=AES-128,URI=zzzKEY");
                    fs.writeFileSync("out.m3u8", out); // ★ .m3u8の保存
                    fs.writeFileSync("zzzKey", urls[keyUrl]); // ★ 鍵データの保存
                }else{
                    console.log("Not found, skip:", keyUrl);
                }
            }
        }
    });
    
    Amazon Elastic Transcoder에서 생성.m3u8된 키 URL은 #EXT-X-KEY:METHOD=AES-128,URI=부터 시작됩니다.따라서 로컬에 저장할 키 데이터를 찾아서 다시 씁니다.(설정에 따라 다르지만 키는 자동으로 생성되기 때문에 키 데이터도HARQ에서 쉽게 얻을 수 있다)

    .ts의 저장


    특별히 기재된 사항이 없다.
    // Extract *.ts
    files.forEach(e => {
        if(e.ext == ".ts"){
            fs.writeFileSync(e.basename, e.blob);
        }
    });
    
    미디어 파일이 여러 개 .ts 로 분할되어 있기 때문에 이 확장자를 가진 파일을 검색하고 저장할 수 있습니다.

    파일 병합


    ...여기는 HLS입니다.나는 js를 쓰고 싶지만 진전이 좋지 않아서 먼저 ffmpeg로 얼렁뚱땅 넘어간다.
    ffmpeg.exe -allowed_extensions ALL -i out.m3u8 -c copy out.ts
    
    출력.ts은 VLC로 정상적으로 재생할 수 있습니다(이것은 당연한 것입니다)

    ToDo, 느낌


    원래는 예산 때문에 애니메이션 기능 자체가 취소돼 토도나 코스가 없었지만, 이 방식으로는 저장할 수 없는 사이트의 설치 방식이 상당히 흥미롭다.남아있는 HTTP를 기록하지 않고 사용자 정의 URI 방안을 준비하며 고객측의 자바스크립트로 출력을 가공하는 방식https://medium.com/@onetdev/custom-key-acquisition-for-encrypted-hls-in-videojs-59e495f78e52이 있습니다.
    올해 WWDC는 로우-lantency 확장https://developer.apple.com/documentation/http_live_streaming/protocol_extension_for_low-latency_hls_preliminary_specification을 제안하는 등 HLS 자체도 계속 확장하고 있지만, 프로토콜 자체의 자바스크립트가 가능한 미디어 소스익스텐션이 되는 아이패드 OS를 정지시키는 절묘한 상황이 계속되고 있다.
    뭐, 플레이 리디의 개발원이 당연하다고 생각하지만, Azure의 서비스와 문서는 AWS보다 충실하다.Azure는'진지한 DRM'으로서 모든 주요 DRM(Widevine, PlayReady, FairPlay)을 지원하고 이를 지원하는 문서https://docs.microsoft.com/ja-jp/azure/media-services/latest/design-multi-drm-system-with-access-control를 제공한다.
    HARQ는 흥미로운 포맷이지만 브라우저의 제작 시기, 스크립트에서 입력한 성능 태그 등 정보를 남기지 못해 현대에선 조금 불만이다.물론 이번과 같은 포장/디버깅도 편리하게 사용할 수 있습니다.오류 보고서에서HARD를 찾는 경우도 있기 때문에 더욱 편리하게 얻기 위해서는 브라우저 확장 같은 것을 먼저 하는 것이 좋다.

    Fiddler Classic으로 하겠습니다.


    가까스로 실제 사이트에서도 시도해 보았다.별로 진지하게 시도하지 않아 아무 말도 못하지만, 실제 사이트에서 디벨로퍼 툴을 열면 스트리밍을 멈출 것 같다.총명하다.
    이 경우 Fiddler의 HARD 1.2 출력을 사용하는 것이 좋습니다.Fiddler의 HARQ 출력도 Firefox와 마찬가지로 용량 제한이 있기 때문에 View→Tabs→Preferences에서 fiddler.importexport.HTTPArchiveJSON.MaxBinaryBodyLength를 적당한 값으로 설정해야 한다.
    Fiddler의 HARQ에 BOM이 첨부되어 있으므로 손으로 깎아야 합니다.또한 Chunked encoding으로 보낸 파일의 디코딩을 수동으로 지정해야 합니다.

    좋은 웹페이지 즐겨찾기