概要
ソラカメで撮影した映像をブラウザで再生するページを作成してみた。
いろいろと注意して実装する必要があるので本記事にまとめる。
ブラウザでLIVE映像を再生させるためには
再生までにやらないといけないこと。
-
SORACOM APIで認証情報を取得する
SORACOM APIリファレンス-認証 -
SORACOM APIを使用して視聴URLを取得する
SORACOM APIリファレンス-視聴URL取得 -
視聴URLを動画プレイヤーに設定する
やってみた
以下、試行錯誤。
下準備
SAMユーザーの作成
SORACOM APIを実行するために下記を実施
-
ソラコム管理画面からSAMユーザーを作成
SAMユーザーの作成 -
作成したSAMユーザーの権限設定で「OAuth2:authorize」「SoraCam:getSoraCamDeviceStreamingVideo」を追加
SAMユーザーの権限追加
{
"statements": [
{
"api": [
"SoraCam:getSoraCamDeviceStreamingVideo",
"OAuth2:authorize"
],
"effect": "allow"
}
]
}
JavaScriptで実装してみた
まずはお手軽にJavaScriptで。
JavaScriptのコード
下記関数を作成。
// 認証情報を取得する
async function authenticate() {
const url = 'https://api.soracom.io/v1/auth';
try {
const response = await axios.post(url, {
authKeyId: 'secret-XXXX',
authKey: 'keyId-XXXX'
}, {
headers: {
'Content-Type': 'application/json'
}
});
console.log("認証成功:", response.data);
// 認証 API のレスポンスに適切なキーがあるか確認
if (!response.data.apiKey || !response.data.token) {
throw new Error("APIキーまたはトークンがレスポンスに含まれていません");
}
return response.data;
} catch (error) {
console.error("認証エラー:", error);
return null; // 認証失敗時は null を返す
}
}
// 視聴URLを取得する
async function getMpd(api_key, api_token) {
const url = 'https://api.soracom.io/v1/sora_cam/devices/[device-id]/images/exports';
try {
const response = await axios.get(url, {
headers: {
'Content-Type': 'application/json',
'X-Soracom-API-Key': api_key,
'X-Soracom-Token': api_token
}
});
console.log("MPD取得成功:", response.data);
// MPD の URL を適切に取得する(レスポンス構造に合わせて変更)
if (!response.data || !response.data.mpd_url) {
throw new Error("MPD URLがレスポンスに含まれていません");
}
return response.data.mpd_url; // MPD URL を返す
} catch (error) {
console.error("MPD取得エラー:", error);
return null; // エラー時は null を返す
}
}
// 動画プレイヤーに視聴URLを設定する
async function setSrc() {
let data = await authenticate(); // 認証を実行
if (!data) {
console.error("認証情報の取得に失敗しました");
return;
}
let mpdUrl = await getMpd(data.apiKey, data.token);
if (!mpdUrl) {
console.error("MPDデータの取得に失敗しました");
return;
}
const myPlayer = videojs("example-video");
myPlayer.src({ type: 'application/dash+xml', src: mpdUrl });
console.log("動画ソースを設定:", mpdUrl);
}
setSrc();
JavaScriptでの問題点
CORSのエラーとなってしまいSORACOM APIの実行ができない。
SORACOM APIの実行処理をAWSのAPI Gatewey+Lambdaへ移植
lambda(python)に移植したコード
import json
import os
import urllib.request
# 環境変数の取得
AUTH_KEY_ID = os.environ['authKeyId']
AUTH_KEY = os.environ['authKey']
DEVICE_ID = os.environ['device_id']
def lambda_handler(event, context):
try:
# 1. 認証してAPIキーとトークンを取得する
auth_response = authenticate()
api_key = auth_response['apiKey']
api_token = auth_response['token']
print("1:OK")
# 2. 視聴URLを返却する
export_url = get_mpd_url(api_key, api_token)
print("2:OK")
return {
'statusCode': 200,
'body': json.dumps({'url': export_url})
}
except Exception as e:
return {
'statusCode': 500,
'body': json.dumps(f'Error: {str(e)}')
}
# 認証を行い、APIキーとトークンを取得
def authenticate():
url = 'https://api.soracom.io/v1/auth'
headers = {
'Content-Type': 'application/json'
}
data = json.dumps({
'authKeyId': AUTH_KEY_ID,
'authKey': AUTH_KEY
}).encode('utf-8')
req = urllib.request.Request(url, headers=headers, data=data, method='POST')
with urllib.request.urlopen(req) as response:
response_code = response.getcode()
if response_code != 200:
raise Exception(f'Authentication failed: {response_code}')
return json.loads(response.read().decode('utf-8'))
# 視聴URLを返却する
def get_mpd_url(api_key, api_token):
url = f'https://api.soracom.io/v1/sora_cam/devices/{DEVICE_ID}/stream'
headers = {
'Content-Type': 'application/json',
'X-Soracom-API-Key': api_key,
'X-Soracom-Token': api_token
}
req = urllib.request.Request(url, headers=headers, method='GET')
with urllib.request.urlopen(req) as response:
response_code = response.getcode()
if response_code != 200:
raise Exception(f'Image export request failed: {response_code}')
export_response = json.loads(response.read().decode('utf-8'))
print(export_response)
return export_response["playList"][0]["url"]
※lambdaの環境変数にソラコムの管理画面から発行した認証キーID(authKeyId)、認証キーシークレット(authKey)を設定しておく
認証キー/認証キーシークレットの取得
※lambdaの環境変数にソラカメの管理画面より取得したデバイスID(device_id)を設定しておく
デバイスIDの取得
実装の参考記事-ソラカメで撮影した画像をwordpressで作成したwebサイトにスライドバーで時刻を選んで表示する!
API Gatewey(REST API) とLambdaを繋げる
別記事参照。
リンク準備中
作成したREST API
https://hoge.execute-api.ap-northeast-1.amazonaws.com/dev/stream
htmlページの用意
動画プレイヤーはvideo.jsを使用
video.jsとは
index.htmlとしてS3に配置
<!DOCTYPE html>
<html>
<head>
<title>LIVE TEST</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<link href="https://vjs.zencdn.net/8.16.1/video-js.css" rel="stylesheet" />
<script src="https://vjs.zencdn.net/8.16.1/videojs-contrib-dash/videojs-dash.js"></script>
</head>
<body>
<div>
<video-js id=example-video width=640 height=360
class="vjs-default-skin" controls>
</video-js>
</div>
<script type="text/javascript" src="https://vjs.zencdn.net/8.16.1/video.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-contrib-dash/5.1.1/videojs-dash.min.js"></script>
<script>
async function getData() {
try {
const response = await fetch("https://hoge.execute-api.ap-northeast-1.amazonaws.com/dev/stream");
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
console.log(JSON.parse(data["body"]).url); // 取得したデータを表示
return JSON.parse(data["body"]).url;
} catch (error) {
console.error("Error:", error);
}
}
async function setupPlayer() {
const myPlayer = videojs("example-video");
try {
const data = await getData(); // 非同期関数の結果を取得
console.log(data);
myPlayer.src({ type: 'application/dash+xml', src: data });
} catch (error) {
console.error("Failed to set video source:", error);
}
}
setupPlayer();
</script>
</body>
</html>
まとめ
- SAMの設定を忘れずに
- JavaScriptだとSORACOM APIを呼び出すときにCORSエラーとなるため、APIを呼ぶ場合は中間サーバーの用意が必用
- ソラカメの視聴URLはMPEG-Dashという配信方式なので一部環境で再生できないので注意
windows Chrome : OK
mac Safari : NG
Android Chrome : OK
iOS Sarari : NG