【検証】インスタライブを自動録画する仕組みを作ってみた結果、無事成功!

インスタライブを自動録画する仕組みを作ってみました。
検証として作成しましたが、特定アカウントがインスタライブを始めたら
自動で録画して、終了後自動的に変換処理が走る仕組みです。

まずは、おことわりです。

おことわり

本記事は、検証のために行なっています。
本記事で行なっている内容を実行すると、
場合によってはインスタグラムのアカウントが凍結する恐れがあります。

また、検証ベースのため必ずしもうまくいくとも限りません。
アップデートによって、本内容では収録できなくなる場合があります。

いかなる場合においても責任を負いませんので、あらかじめご了承ください。

実装したこと

環境はubuntu

crontabを使用して定期的に以下を実行。
・インスタのログイン情報(クッキーファイル)が存在するかチェック
・無ければログインを行う。→ローカルにクッキーをtxtで保存
・インスタライブのURLをcurlでリクエストを送信
・レスポンスのステータスコードが200であったら、pyinstaliveを使用して録画を開始
・レスポンスのステータスコードが302のうち
ログインURLにリダイレクトされていたら、再ログイン
ログインURL以外であれば、配信中でない

のように実行しました。

webhook等も制限が厳しく、他のユーザの情報を取得できなかったりします。
IFTTT等サードパーティ系のサービスでも取得できなかったので、致し方なく定期ジョブにしました。

また、インスタの情報や動画、写真を取得するのに様々なモジュールやらアプリやらあるのですが、インスタの度重なるアップデート(対策)により使用不可となり更新も途絶えていたりして、なかなか使用できるものが限られていました。
また、ライブはストリーミングのため動画保存とは違ってひと工夫が必要です。
(FFmpegが対応してたら楽なんですがね、検証で失敗したので使用しませんでした。)

実装してみた

フォルダ構成等は、上記の画像の通りです。
とにかく簡易的に実装したので
構成であったりソース等、破茶滅茶なのでご容赦ください。

①pyinstaliveを導入

githubから、PyInstaLive を落としてきましょう。
すでに開発は止まっており、不具合等は修正されないので
issueで挙げられている問題に関してプルリクの内容に従って修正する必要があります。

現時点では、Fix get csrf_token issue #154 の対処のみで問題なく使用できるようになりました。

②pyinstalive.iniを作成

[pyinstalive]
username = userid
password = password
download_path = /home/instagram-rec/videos
download_comments = True
clear_temp_files = True
cmd_on_started =
cmd_on_ended =
ffmpeg_path = 
log_to_file = True
no_assemble = False
use_locks = True
send_heartbeat = True
proxy =

usernameとpasswordは、自身のアカウントの情報を入力しましょう。
(検証用でアカウントを作ったほうが良いでしょう。凍結される恐れあり)

download_pathで動画を置くパスを指定、download_commentsでコメントも取得するかを指定します。他は基本的には標準の設定のままにしています。

download_commentsをtrueにすると、json形式で配信中のメッセージを記録します。

③rec.shを作成

#!/bin/bash

USERNAME="username"
LIVE_CHECK_URL="https://www.instagram.com/${USERNAME}/live/?hl=ja"
LOGIN_URL="https://www.instagram.com/accounts/login/"
LOG_FILE="/home/instagram-rec/pyinstalive/event.log"

log_message() {
    echo "$(date +'%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}

# PyInstaLiveが稼働中か確認
if pgrep -f pyinstalive > /dev/null; then
    log_message "PyInstaLiveで収録中のため処理を行わない。"
    exit 0
fi

# cookie.txt を使ってリクエストを送信
cookie_file="/home/instagram-rec/pyinstalive/cookie.txt"

# クッキーを読み込み
cookies=$(awk -F= '{printf "%s=%s; ", $1, $2}' $cookie_file | sed 's/; $//')

# クッキーを使ってリクエストを送信
response=$(curl -s -o /dev/null -w "%{http_code}" -b "$cookies" $LIVE_CHECK_URL)

# ステータスコードを確認
if [ "$response" -eq 200 ]; then
    log_message "PyInstaLiveで収録を開始。"
    pyinstalive -d "$USERNAME"
elif [ "$response" -eq 302 ]; then
    # リダイレクト先を確認
    redirect_url=$(curl -s -I -b "$cookies" $LIVE_CHECK_URL | grep -i Location | awk '{print $2}')
    #log_message "リダイレクト先のURL: $redirect_url"
    if [[ "$redirect_url" == *"$LOGIN_URL"* ]]; then
        log_message "セッションが切れました。再ログインが必要です。"
        python3 /home/instagram-rec/script/login.py
    else
        log_message "ライブ中ではありません。"
    fi
else
    log_message "ライブ配信の確認に失敗しました。ステータスコード: $response"
fi

USERNAMEには、録画したいユーザのusernameを入力します。
対象のユーザのプロフィール画面を開けた時のURLにある識別子です。

PyInstaLiveのプロセスをpgrepで確認し稼働中のときは、その後の処理を行いません。
その後、cookie.txtを使いインスタライブのURLにアクセスし、ステータスコードを確認します。

ステータスコードが200のときは、ライブ配信中ですのでPyInstaLiveを実行し収録します。
ステータスコードが302のときは、ログイン画面にリダイレクトもしくは、対象ユーザのプロフィール画面にリダイレクトされます。

ログイン画面であれば、ログインが切れているのでlogin.py(再ログイン)を実行します。
プロフィール画面であれば、インスタライブは配信中ではないと判定します。

④login.pyを作成

import requests
import json
from datetime import datetime

# ログイン情報
username = 'username'
password = 'password'

# URLとヘッダーの設定
link = 'https://www.instagram.com/accounts/login/'
login_url = 'https://www.instagram.com/accounts/login/ajax/'

# 現在のタイムスタンプ
time = int(datetime.now().timestamp())

# CSRFトークンの取得
response = requests.get(link)
csrf = response.cookies['csrftoken']

# ログインリクエストのペイロード
payload = {
    'username': username,
    'enc_password': f'#PWD_INSTAGRAM_BROWSER:0:{time}:{password}',
    'queryParams': {},
    'optIntoOneTap': 'false'
}

# ログインリクエストのヘッダー
login_header = {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36",
    "X-Requested-With": "XMLHttpRequest",
    "Referer": link,
    "x-csrftoken": csrf
}

# ログインリクエストの送信
login_response = requests.post(login_url, data=payload, headers=login_header)

# レスポンスの内容確認
if login_response.status_code == 200:
    try:
        json_data = login_response.json()
        if json_data.get('authenticated'):
            print('ログイン成功!')
            cookies = login_response.cookies.get_dict()
            
            # クッキーの保存
            cookie_path = '/home/instagram-rec/pyinstalive/cookie.txt'
            with open(cookie_path, 'w') as file:
                for key, value in cookies.items():
                    file.write(f'{key}={value}\n')
            print('クッキーをcookie.txtに保存しました')
        else:
            print('ログイン失敗', json_data)
    except json.JSONDecodeError:
        print('レスポンスがJSON形式ではありません', login_response.text)
else:
    print('ログインリクエスト失敗', login_response.status_code, login_response.text)

ソースにベタ書きですが、ユーザID、パスワードはpyinstaliveにも記した自身のアカウントのものです。

ログインに成功したら、Cookie情報をcookie.txtに転記します。

⑤crontabの設定

これらを定期実行するためcrontabを使用します。

以下コマンドで設定を編集します。

crontab -e

以下を追記しました。

*/10 21-23,0-7 * * * /home/instagram-rec/script/rec.sh >> /home/instagram-rec/pyinstalive/event.log 2>&1

私は、21~7時まで間、10分おきに実行するように設定しました。

設定方法は自由ですが、一定時間に連続してアクセスするとBot判定されるので
10〜30分は間隔をあけた方がよいでしょう。

その分、収録開始時間は遅れてしまいますが、Bot判定されて収録できないよりかはマシですね。

動かしてみた

問題なく、収録できました。
コメントもjsonで出力することができました。

しかしながらチューニング中なので成功率は30%程度です。
定期実行の時間が短すぎるとブロックされるので、、今のところは10分でうまくいきます。
あとは、pyinstaliveでの動画変換中にエラーで止まったみたいで、失敗しました。
おそらく仮想環境のスペック不足です。

無事成功した動画では、音の遅れや映像の乱れはありません。

本当は、定期実行ではなく対象ユーザのインスタライブ配信開始通知をトリガーとしてやりたかったですが、なかなか制限があり厳しいみたいです。

本内容は検証なのでクローズしますが、
あまり実用的でもありませんし、グレーなので諦めて
頑張って目をギンギンにして、リアタイで視聴しましょう。

コメント

スポンサーリンク
スポンサーリンク
タイトルとURLをコピーしました