Search code examples
ffmpegflowplayermpeg2-ts

How to process .ts files used by flowplayer?


Flowplay seems to be used by jove.com

https://www.jove.com/video/59612/3d-kinematic-gait-analysis-for-preclinical-studies-in-rodents

Take the above URL as an example, it will use .ts files like this (via Google Chrome devtools)

https://cloudflare2.jove.com/CDNSource/hls/59612/59612_3.ts

But I am not sure how to make the .ts file viewable locally.

https://askubuntu.com/questions/3645/how-do-i-convert-ts-files-into-something-useful

I tried something like this. But I always get errors.

$ ffmpeg -i 50191_1.ts -c:v libx264 -crf 0 -c:a copy output.mp4
ffmpeg version 4.0.2 Copyright (c) 2000-2018 the FFmpeg developers
  built with Apple LLVM version 9.1.0 (clang-902.0.39.2)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.0.2 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-gpl --enable-libmp3lame --enable-libx264 --enable-libxvid --enable-opencl --enable-videotoolbox --disable-lzma
  libavutil      56. 14.100 / 56. 14.100
  libavcodec     58. 18.100 / 58. 18.100
  libavformat    58. 12.100 / 58. 12.100
  libavdevice    58.  3.100 / 58.  3.100
  libavfilter     7. 16.100 /  7. 16.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  1.100 /  5.  1.100
  libswresample   3.  1.100 /  3.  1.100
  libpostproc    55.  1.100 / 55.  1.100
50191_1.ts: Invalid data found when processing input

Does anybody know how to convert the .ts files?

EDIT: I got something like this.

$ cat 59612_.m3u8
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:17
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="https://cloudflare2.jove.com/CDNSource/hls/59612/59612.key"
#EXTINF:16.683333,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_0.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_1.ts
#EXTINF:6.606600,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_2.ts
#EXTINF:16.683333,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_3.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_4.ts
#EXTINF:10.877533,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_5.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_6.ts
#EXTINF:7.907900,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_7.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_8.ts
#EXTINF:10.910900,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_9.ts
#EXTINF:9.676333,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_10.ts
#EXTINF:8.375033,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_11.ts
#EXTINF:12.645967,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_12.ts
#EXTINF:13.146467,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_13.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_14.ts
#EXTINF:6.840167,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_15.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_16.ts
#EXTINF:10.877533,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_17.ts
#EXTINF:16.683333,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_18.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_19.ts
#EXTINF:6.706700,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_20.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_21.ts
#EXTINF:16.683333,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_22.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_23.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_24.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_25.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_26.ts
#EXTINF:16.649967,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_27.ts
#EXTINF:8.308300,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_28.ts
#EXTINF:8.308300,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_29.ts
#EXTINF:5.672333,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_30.ts
#EXTINF:10.677333,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_31.ts
#EXTINF:16.683333,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_32.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_33.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_34.ts
#EXTINF:7.507500,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_35.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_36.ts
#EXTINF:16.683333,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_37.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_38.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_39.ts
#EXTINF:7.273933,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_40.ts
#EXTINF:16.683333,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_41.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_42.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_43.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_44.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_45.ts
#EXTINF:16.683333,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_46.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_47.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_48.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_49.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_50.ts
#EXTINF:16.683333,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_51.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_52.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_53.ts
#EXTINF:13.079733,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_54.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_55.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_56.ts
#EXTINF:13.113100,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_57.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_58.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_59.ts
#EXTINF:8.341667,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_60.ts
#EXTINF:6.573233,
https://cloudflare2.jove.com/CDNSource/hls/59612/59612_61.ts
#EXT-X-ENDLIST

Solution

  • #EXT-X-KEY:METHOD=AES-128,URI="https://cloudflare2.jove.com/CDNSource/hls/59612/59612.key"

    This HLS videostream is encrypted. AES-128 is not DRM, so with the key present it can be decrypted.

    HLS videostream

    The easy way is to just open the HLS videostream with FFmpeg (which it automatically decrypts) and cut the desired segment:

    ffmpeg -ss 32 -i https://cloudflare2.jove.com/CDNSource/hls/59612/59612_.m3u8 -t 17 -c copy output.mp4
    
    • -ss 32: skip to 32s.
    • -t 17: set duration to 17s.
    • -c copy: perform a stream-copy (no loss in quality).

    Individual segment

    This requires you to decrypt the segment yourself.

    When you download the decryption key 59612.key, you'll see a lot of gibberish: Aæª~ý÷øŽ©ýÛO®ø.
    You'll have to convert this to a hex binary representation. This can be done with hexdump...

    curl -s https://cloudflare2.jove.com/CDNSource/hls/59612/59612.key | hexdump -e '16/1 "%02x"
    41e61c18aa7efdf7f88ea9fddb4faef8
    

    ...or with one of my favorite tools, xidel:

    xidel -s https://cloudflare2.jove.com/CDNSource/hls/59612/59612.key -e 'x:string-to-hexBinary($raw)'
    41E61C18AA7EFDF7F88EA9FDDB4FAEF8
    

    Next you can decrypt the 60th segment (for instance) with ffmpeg:

    ffmpeg \
    -key 41E61C18AA7EFDF7F88EA9FDDB4FAEF8 \
    -iv 0000000000000000000000000000003C \
    -i crypto:https://cloudflare2.jove.com/CDNSource/hls/59612/59612_60.ts \
    -c copy \
    output.mp4
    
    • -iv 0000000000000000000000000000003C: 60 (decimal) = 3C (hexa-decimal).

    ...or with openssl:

    openssl \
    aes-128-cbc \
    -in <(curl -s https://cloudflare2.jove.com/CDNSource/hls/59612/59612_60.ts) \
    -out 59612_60-decrypted.ts \
    -d -iv 60 -K 41E61C18AA7EFDF7F88EA9FDDB4FAEF8