twitterのspaceによる音声配信は、m3u8ファイルを使用してのhttpsによるaacファイルの配布という形で実現されている。
streamlinkにm3u8ファイルのURLを与えると音声ファイルが取得できるので、これを自動化できないか検討している。
まず第1歩として、指定したユーザのタイムラインでspace配信のURLがあった場合に検出できないかを確認。
単純にwgetやcurlで「curl -s https://twitter.com/niselog/」とやっても発言は拾えない。
python-twitterのマニュアルを見ながらpythonスクリプトを作成
#!/usr/bin/python
import os
import twitter
token='文字列'
token_secret='文字列'
consumer_key = '文字列'
consumer_secret='文字列'
t = twitter.Api(consumer_key=consumer_key,
consumer_secret=consumer_secret,
access_token_key=token,
access_token_secret=token_secret)
for line in t.GetUserTimeline(screen_name="niselog"):
print line
これを実行すると、下記の様な出力になる
-bash-4.2$ ./test3.py |tail -2
{"created_at": "Sat May 14 08:13:22 +0000 2016", "hashtags": [{"text": "\u30b1\u30eb\u30d9\u30ed\u30b9\u30d6\u30ec\u30a4\u30c9"}], "id": 731396977758339072, "id_str": "731396977758339072", "lang": "ja", "source": "<a href=\"https://about.twitter.com/products/tweetdeck\" rel=\"nofollow\">TweetDeck</a>", "text": "\u507d\u30ed\u30b0 for #\u30b1\u30eb\u30d9\u30ed\u30b9\u30d6\u30ec\u30a4\u30c9 \u306f\u30b1\u30eb\u30d9\u30ed\u30b9\u8d85\u4f1a\u8b70\u306e\u4e00\u89a7\u30da\u30fc\u30b8\u306b\u5bfe\u5fdc\u3057\u307e\u3057\u305f https://t.co/gDlRyiFWC3", "urls": [{"expanded_url": "http://tw5.niselog.jp/", "url": "https://t.co/gDlRyiFWC3"}], "user": {"created_at": "Mon Mar 01 05:51:23 +0000 2010", "default_profile": true, "default_profile_image": true, "description": "\u30c8\u30df\u30fc\u30a6\u30a9\u30fc\u30ab\u30fcPBW \u7121\u9650\u306e\u30d5\u30a1\u30f3\u30bf\u30b8\u30a2/\u30b7\u30eb\u30d0\u30fc\u30ec\u30a4\u30f3/\u30a8\u30f3\u30c9\u30d6\u30ec\u30a4\u30ab\u30fc\uff01/\u30b5\u30a4\u30ad\u30c3\u30af\u30cf\u30fc\u30c4\u3078\u306e\u643a\u5e2f\u5411\u3051\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u30b5\u30fc\u30d3\u30b9\u300c\u507d\u30ed\u30b0\u300d\u306e\u7ba1\u7406\u8005\u30a2\u30ab\u30a6\u30f3\u30c8\u3067\u3059\u3002 http://t.co/QMKlQjzjSI http://t.co/YEiNJUvGdU", "followers_count": 40, "id": 118604209, "id_str": "118604209", "listed_count": 5, "name": "niselog \u7ba1\u7406\u8005", "profile_background_color": "C0DEED", "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png", "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png", "profile_image_url": "http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png", "profile_image_url_https": "https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png", "profile_link_color": "1DA1F2", "profile_sidebar_border_color": "C0DEED", "profile_sidebar_fill_color": "DDEEF6", "profile_text_color": "333333", "profile_use_background_image": true, "screen_name": "niselog", "statuses_count": 340, "url": "http://t.co/QMKlQjzjSI", "withheld_in_countries": []}, "user_mentions": []}
{"created_at": "Sat May 14 07:02:08 +0000 2016", "hashtags": [], "id": 731379051852505088, "id_str": "731379051852505088", "lang": "ja", "retweet_count": 2, "source": "<a href=\"https://about.twitter.com/products/tweetdeck\" rel=\"nofollow\">TweetDeck</a>", "text": "\u7121\u9650\u306e\u30d5\u30a1\u30f3\u30bf\u30b8\u30a2\u3001\u30b7\u30eb\u30d0\u30fc\u30ec\u30a4\u30f3\u3001\u30a8\u30f3\u30c9\u30d6\u30ec\u30a4\u30ab\u30fc\u5411\u3051\u306e\u507d\u30ed\u30b0 https://t.co/QMKlQjzjSI \u3067\u3059\u304c\u3001\u590f\u9803\u306b\u5b8c\u5168\u505c\u6b62\u3059\u308b\u4e88\u5b9a\u3067\u3059\u3002(URL\u306f\u6b8b\u308a\u307e\u3059\u304c)", "urls": [{"expanded_url": "http://niselog.jp/", "url": "https://t.co/QMKlQjzjSI"}], "user": {"created_at": "Mon Mar 01 05:51:23 +0000 2010", "default_profile": true, "default_profile_image": true, "description": "\u30c8\u30df\u30fc\u30a6\u30a9\u30fc\u30ab\u30fcPBW \u7121\u9650\u306e\u30d5\u30a1\u30f3\u30bf\u30b8\u30a2/\u30b7\u30eb\u30d0\u30fc\u30ec\u30a4\u30f3/\u30a8\u30f3\u30c9\u30d6\u30ec\u30a4\u30ab\u30fc\uff01/\u30b5\u30a4\u30ad\u30c3\u30af\u30cf\u30fc\u30c4\u3078\u306e\u643a\u5e2f\u5411\u3051\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u30b5\u30fc\u30d3\u30b9\u300c\u507d\u30ed\u30b0\u300d\u306e\u7ba1\u7406\u8005\u30a2\u30ab\u30a6\u30f3\u30c8\u3067\u3059\u3002 http://t.co/QMKlQjzjSI http://t.co/YEiNJUvGdU", "followers_count": 40, "id": 118604209, "id_str": "118604209", "listed_count": 5, "name": "niselog \u7ba1\u7406\u8005", "profile_background_color": "C0DEED", "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png", "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png", "profile_image_url": "http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png", "profile_image_url_https": "https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png", "profile_link_color": "1DA1F2", "profile_sidebar_border_color": "C0DEED", "profile_sidebar_fill_color": "DDEEF6", "profile_text_color": "333333", "profile_use_background_image": true, "screen_name": "niselog", "statuses_count": 340, "url": "http://t.co/QMKlQjzjSI", "withheld_in_countries": []}, "user_mentions": []}
-bash-4.2$
unicode escapeという形式で文字が表示されているので読めない。
全体的にみてみるとJSON形式のデータになっているのでjqコマンドを通して見た。
-bash-4.2$ ./test3.py |tail -2|jq .
{
"created_at": "Sat May 14 08:13:22 +0000 2016",
"hashtags": [
{
"text": "ケルベロスブレイド"
}
],
"id": 731396977758339100,
"id_str": "731396977758339072",
"lang": "ja",
"source": "<a href=\"https://about.twitter.com/products/tweetdeck\" rel=\"nofollow\">TweetDeck</a>",
"text": "偽ログ for #ケルベロスブレイド はケルベロス超会議の一覧ページに対応しました https://t.co/gDlRyiFWC3",
"urls": [
{
"expanded_url": "http://tw5.niselog.jp/",
"url": "https://t.co/gDlRyiFWC3"
}
],
"user": {
"created_at": "Mon Mar 01 05:51:23 +0000 2010",
"default_profile": true,
"default_profile_image": true,
"description": "トミーウォーカーPBW 無限のファンタジア/シルバーレイン/エンドブレイカー!/サイキックハーツへの携帯向けゲートウェイサービス「偽ログ」の管理者 アカウントです。 http://t.co/QMKlQjzjSI http://t.co/YEiNJUvGdU",
"followers_count": 40,
"id": 118604209,
"id_str": "118604209",
"listed_count": 5,
"name": "niselog 管理者",
"profile_background_color": "C0DEED",
"profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png",
"profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png",
"profile_image_url": "http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png",
"profile_image_url_https": "https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png",
"profile_link_color": "1DA1F2",
"profile_sidebar_border_color": "C0DEED",
"profile_sidebar_fill_color": "DDEEF6",
"profile_text_color": "333333",
"profile_use_background_image": true,
"screen_name": "niselog",
"statuses_count": 340,
"url": "http://t.co/QMKlQjzjSI",
"withheld_in_countries": []
},
"user_mentions": []
}
{
"created_at": "Sat May 14 07:02:08 +0000 2016",
"hashtags": [],
"id": 731379051852505100,
"id_str": "731379051852505088",
"lang": "ja",
"retweet_count": 2,
"source": "<a href=\"https://about.twitter.com/products/tweetdeck\" rel=\"nofollow\">TweetDeck</a>",
"text": "無限のファンタジア、シルバーレイン、エンドブレイカー向けの偽ログ https://t.co/QMKlQjzjSI ですが、夏頃に完全停止する予定です。(URLは残りますが)",
"urls": [
{
"expanded_url": "http://niselog.jp/",
"url": "https://t.co/QMKlQjzjSI"
}
],
"user": {
"created_at": "Mon Mar 01 05:51:23 +0000 2010",
"default_profile": true,
"default_profile_image": true,
"description": "トミーウォーカーPBW 無限のファンタジア/シルバーレイン/エンドブレイカー!/サイキックハーツへの携帯向けゲートウェイサービス「偽ログ」の管理者 アカウントです。 http://t.co/QMKlQjzjSI http://t.co/YEiNJUvGdU",
"followers_count": 40,
"id": 118604209,
"id_str": "118604209",
"listed_count": 5,
"name": "niselog 管理者",
"profile_background_color": "C0DEED",
"profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png",
"profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png",
"profile_image_url": "http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png",
"profile_image_url_https": "https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png",
"profile_link_color": "1DA1F2",
"profile_sidebar_border_color": "C0DEED",
"profile_sidebar_fill_color": "DDEEF6",
"profile_text_color": "333333",
"profile_use_background_image": true,
"screen_name": "niselog",
"statuses_count": 340,
"url": "http://t.co/QMKlQjzjSI",
"withheld_in_countries": []
},
"user_mentions": []
}
-bash-4.2$
今度は可読できる状態になった。
で・・・twitter spaceの場合、次のような出力になっていた
{
"created_at": "Fri Aug 13 02:11:56 +0000 2021",
"hashtags": [],
"id": ~,
"id_str": "~",
"lang": "ja",
"source": "<a href=\"http://twitter.com/download/android\" rel=\"nofollow\">Twitter for Android</a>",
"text": "スペース配信開始\nhttps://t.co/~",
"urls": [
{
"expanded_url": "https://twitter.com/i/spaces/~",
"url": "https://t.co/~"
}
],
"user": {
<略>
}
}
urlsにexpanded_urlという項目があり、そこに /i/spaces/~ というtwitter spaceのURLが書かれているという状態であった。
とりあえず、これで、twitter spaceに参加するためのURLは取得できそう。
jqコマンドのオプションを変えて.urlsだけを抜き出して見る
-bash-4.2$ ./test3.py|jq '.urls'
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[
{
"expanded_url": "https://twitter.com/i/spaces/~",
"url": "https://t.co/~"
}
]
[
{
"expanded_url": "https://~",
"url": "https://t.co/~"
}
]
[]
[]
[]
[]
[]
[]
[]
[]
-bash-4.
中身が入ってないものまで表示されてしまう。
「jq コマンドを使う日常のご紹介」になかなかいい参考事例を発見
-bash-4.2$ ./test3.py|jq -r '.urls[] '
{
"expanded_url": "https://twitter.com/i/spaces/~",
"url": "https://t.co/~"
}
{
"expanded_url": "https://~",
"url": "https://t.co/~"
}
-bash-4.2$
これでURLがある場合だけ結果が出た。
もう1歩すすめてjqコマンドマニュアルみつつselectで完全一致だけ出力
-bash-4.2$ ./test3.py|jq -r '.urls[] |select(.expanded_url == "https://twitter.com/i/spaces/~")'
{
"expanded_url": "https://twitter.com/i/spaces/~",
"url": "https://t.co/~"
}
-bash-4.2$
部分一致を探すとstartswith
,endswith
で指定文字列で始まる場合/終わる場合を条件にできた
-bash-4.2$ ./test3.py|jq -r '.urls[] | select(.expanded_url | startswith("https://twitter.com/i/spaces/"))'
{
"expanded_url": "https://twitter.com/i/spaces/~",
"url": "https://t.co/~"
}
-bash-4.2$
含まれる場合は containsでいけた
-bash-4.2$ ./test3.py|jq -r '.urls[] | select(.expanded_url | contains("https://
twitter.com/i/spaces/"))'
{
"expanded_url": "https://twitter.com/i/spaces/~",
"url": "https://t.co/~"
}
-bash-4.2$