LINE LIVE を眺めた(アプリ限定も録画したかった件)

WM2Bl_iA.png
こんばんは。内容は保証しません、というかただのメモ。

6月に調べて諦めてた案件です。

FRESH by AbemaTV を眺めた

FRESH by AbemaTV をもう一度眺めた(仕様改変に対応する)
http://nyarudiary.blog.fc2.com/blog-entry-107.html

の派生、というかLINELIVEバージョン。

いつも通りffmpegを使用していきます。

システム上すべての番組はアーカイブが(公開非公開別として)作られています。

生放送後にアーカイブを非公開にする番組(このページは削除されましたと出る)や、アプリ限定公開の番組は、放送中に以下のハッシュをメモしておけば、番組頭から保存したり、見返すことが可能です。

PCで見れるタイプのものは、ブラウザの通信を監視していれば

番組ハッシュ/720/chunklist.m3u8
みたいなのが降ってきますので、そのまま投げればOKです。

他の解像度が欲しい場合、同時に降ってくる

番組ハッシュ(LIVEの場合)
番組ハッシュ(VODの場合)
live/pba/XXXというのもありますが、何故分けているのかは不明。

LIVE配信の場合、上の中身は

{
“type” : “live”,
“playUrls” : {
“abr” : “http://lss.line-cdn.net/p/live/XYZ(例外)/abr.m3u8”,
“144” : “http://lss.line-cdn.net/p/live/XXX/144/chunklist.m3u8”,
“aac” : “http://lss.line-cdn.net/p/live/XXX/aac/chunklist.m3u8”,
“720” : “http://lss.line-cdn.net/p/live/XXX/720/chunklist.m3u8”,
“480” : “http://lss.line-cdn.net/p/live/XXX/480/chunklist.m3u8”,
“360” : “http://lss.line-cdn.net/p/live/XXX/360/chunklist.m3u8”,
“240” : “http://lss.line-cdn.net/p/live/XXX/240/chunklist.m3u8”
},
“imgUrl” : “https://scdn.line-apps.com/obs/r/live/ba/番組ハッシュ__lastscene.jpg”,
“snapshots” : null
}

※生配信のabrだけハッシュが別
→生のabrにはスマホユーザーが集中するからだろうか?
配信終了後は

{“code”:40,”message”:”not found live streaming.”}

VODの場合は

{
“type” : “vod”,
“playUrls” : {
“abr” : “http://lss.line-cdn.net/vod/XXX/abr.m3u8”,
“144” : “http://lss.line-cdn.net/vod/XXX/144.m3u8”,
“aac” : “http://lss.line-cdn.net/vod/XXX/aac.m3u8”,
“720” : “http://lss.line-cdn.net/vod/XXX/720.m3u8”,
“480” : “http://lss.line-cdn.net/vod/XXX/480.m3u8”,
“360” : “http://lss.line-cdn.net/vod/XXX/360.m3u8”,
“240” : “http://lss.line-cdn.net/vod/XXX/240.m3u8”
},
“imgUrl” : “https://scdn.line-apps.com/obs/XXXXXX/f960x540”,
“snapshots” : [ {
“url” : “http://lss.line-cdn.net/img/XXXXXX”,
“posSec” : 500
}, {
“url” : “http://lss.line-cdn.net/img/XXXXXX”,
“posSec” : 1500
}, {
“url” : “http://lss.line-cdn.net/img/XXXXXX”,
“posSec” : 2500
}, {
“url” : “http://lss.line-cdn.net/img/XXXXXX”,
“posSec” : 3500
}, {
“url” : “http://lss.line-cdn.net/img/XXXXXX”,
“posSec” : 4500
} ]
}

※VODは複数のサムネが生成されるようだ。

となっており、abr(Adaptive BitRate streaming用?)他、5種類の解像度+音声が定義されていました。
6月時点では音声のみのストリーム(aac)は無かったので、ラジオ向きの改善、ってことなんでしょうかね。

Fresh by AbemaTVの場合、”番組ID”はURLから見つけられますが、LINLIVEの場合はちょっとややこしい。
一応ここでは番組IDならぬ番組ハッシュとでも呼びましょうか(今更。

\生放送中に/

https://live.line.me/r/channels/チャンネルID/broadcast/番組ID

<meta property=”og:image” content=”https://scdn.line-apps.com/obs/r/live/ba/番組ハッシュ__lastscene.jpg/f960x540″>

番組ページのメタデータ(OGP=Open Graph protocol)から番組ハッシュをコピーしてplayinfoを得ることができました。
アプリ限定公開でもここは変わりません。

\放送が終わると/

<meta property=”og:image” content=”https://scdn.line-apps.com/obs/XXXXXX/f960x540″>
に変わっていました。これは番組IDではないです。

アーカイブが公開されていればplayInfoは降ってくるので調べる必要はありません。
非公開・限定公開の場合も番組ページにヒント「”data-broadcast”」が有りますので頑張って探すと良いかと。
→番組ページが消えていたらGoogle他のキャッシュを当たるとOK。大抵何処かのロボットが巡回してます。

最後に保存編。
/720.m3u8、または/720/chunklist.m3u8
中身はこんな感じ。
無題
音声のビットレートはFresh by AbemaTVより高めのAAC(LC) VBR192kbps/22.05KHz。
映像H.264_AVC BP@L4.1、VBRでMax.2200kbps、Freshより低め。
可変フレームレートなのは同じ。Baseなのか…とも思いますが幅広く、という点では良いかと。
まぁ配信者がスマホからだったりするので大して意味は無い。

というわけで先程のplayinfoで得られたメディアプレイリストをffmpegに投げて保存完了。
MPEG2-TSコンテナの仕様の違いによりそのままtsで保存すると多分シークに失敗します。

ffmpeg.exe -i “http://lss.line-cdn.net/p/live/XXX/720/chunklist.m3u8” -c copy -bsf aac_adtstoasc out.mp4

ffmpeg.exe -i “http://lss.line-cdn.net/vod/XXX/720.m3u8” -c copy -bsf aac_adtstoasc out.mp4

ストリーミング対応にするなら、-movflags faststartをつける。

追記:一部修正しました。各種配信メディアはユーザーの取り合いで本当に大変そうです。LINELIVEはオタク配信向けでは、ない、ですね。