目次
Amazon Interactive Video Service (IVS) v2.0 完全ガイド 2026
概要
Amazon Interactive Video Service(IVS) は、低レイテンシのライブストリーミングサービスであり、Twitch の技術をベースに 300 ミリ秒以下の超低遅延ライブ配信を提供します。ゲームライブ配信・ライブショッピング・リアルタイムオークション・バーチャルイベント・ライブホーム販売などのインタラクティブなライブ体験を構築できます。2024-2026年間に IVS Chat・IVS Real-Time Streaming(WebRTC ベース)・360度コンテンツ対応を拡張。
解決する課題
超低遅延によるインタラクション実現
- YouTube Live・Twitch は 5-30 秒の遅延がありチャット双方向性が成立しないが、IVS は 300ms 以下で配信者とリアルタイムチャットが可能
自動マルチビットレート配信
- トランスコード・CDN・スケーリングを自動管理、5秒で数万視聴者対応可能
タイムドメタデータ同期
- ライブ映像に同期したメタデータ(商品情報・投票・クイズ)を埋め込んでインタラクティブ体験
リアルタイムチャット統合
- IVS Chat で最大 10,000 同時接続チャットルーム、Lambda でメッセージモデレーション
低コスト・マネージド
- インフラ管理不要でスケーラビリティを自動提供、従量課金で無駄を排除
アーキテクチャ全体
配信者(ストリーマー)層:
PC(OBS / FFmpeg)or スマートフォン
├─ RTMP/RTMPS(インジェスト)
│ rtmps://a1bcdef34ghij.global-contribute.live-video.net:443/app/
│ Stream Key: sk_xxxxx
└─ Bitrate: 3-8 Mbps, Resolution: 1080p, FPS: 30-60
IVS インジェスト層:
┌────────────────────────────────────────────────────┐
│ IVS Ingest(Twitch インフラベース) │
│ ├─ RTMP/RTMPS エンコーダー対応 │
│ ├─ SRT(Secure Reliable Transport)対応 │
│ ├─ DASH/HLS への自動トランスコード │
│ ├─ マルチビットレート(ABR)生成 │
│ └─ 冗長性・自動フェイルオーバー │
└────────────────────────────────────────────────────┘
ライブ配信サービス層:
┌────────────────────────────────────────────────────┐
│ IVS Service Plane │
│ ├─ Live-to-VOD 記録(S3 自動保存) │
│ ├─ Timed Metadata(タイムコード付きメタデータ)│
│ ├─ Recording Configuration(品質設定) │
│ ├─ Playback Authorization(署名付き再生 URL) │
│ └─ Thumbnail Auto-Generation │
└────────────────────────────────────────────────────┘
チャット層:
┌────────────────────────────────────────────────────┐
│ IVS Chat (WebSocket) │
│ ├─ リアルタイムメッセージ配信 │
│ ├─ Lambda メッセージレビューハンドラー │
│ ├─ Max 10,000 同時接続 │
│ └─ メッセージ履歴保存(CloudWatch Logs) │
└────────────────────────────────────────────────────┘
Real-Time Streaming 層(IVS Stages):
┌────────────────────────────────────────────────────┐
│ IVS Real-Time Streaming (WebRTC) │
│ ├─ Max 12 ホスト(カメラ・画面共有) │
│ ├─ Max 10,000 視聴者 │
│ ├─ Latency: <300ms │
│ └─ Composition Engine(レイアウト自動生成) │
└────────────────────────────────────────────────────┘
視聴者(プレーヤー)層:
Web / iOS / Android / Smart TV
├─ IVS Player SDK(HLS/DASH)
│ ↓ CloudFront CDN(自動統合)
├─ 遅延: <5 秒(Low Latency)
├─ 解像度: 1080p, 720p, 480p, 360p(自動適応)
└─ 同期メタデータ受信(Timed Metadata)
外部統合:
Lambda → メッセージモデレーション・メトリクス集約
EventBridge → セッション開始/終了イベント
S3 → ライブ配信アーカイブ保存
CloudWatch → 監視・ログ
チャンネルの作成と設定
# IVS チャンネル作成(基本)
aws ivs create-channel \
--name my-livestream \
--type STANDARD \ # BASIC / STANDARD / ADVANCED_HD
--latency-mode ULTRA_LOW \ # NORMAL(6-12s) / LOW(3s) / ULTRA_LOW(300ms)
--authorized true \ # PlaybackAuthorization 必須
--tags Key=Environment,Value=Production Key=App,Value=LiveCommerce
# チャンネル確認
aws ivs get-channel \
--arn arn:aws:ivs:us-east-1:123456789012:channel/AbCdEfGh
# ストリームキー作成(配信者用)
aws ivs create-stream-key \
--channel-arn arn:aws:ivs:us-east-1:123456789012:channel/AbCdEfGh
# レコーディング設定(Live-to-VOD)
aws ivs create-recording-configuration \
--destination-configuration '[
{
"S3": {
"BucketName": "my-ivs-archive-bucket",
"RecordingPathPrefix": "live-archive/2026/",
"EncryptionKey": {
"Arn": "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
}
}
}
]' \
--thumbnail-configuration '{"RecordingMode": "INTERVAL", "TargetIntervalSeconds": 60}'
# チャンネルにレコーディング設定をアタッチ
aws ivs update-channel \
--arn arn:aws:ivs:us-east-1:123456789012:channel/AbCdEfGh \
--recording-configuration-arn arn:aws:ivs:us-east-1:123456789012:recording-configuration/xxxxx
# Playback Authorization キーペア(署名付き再生 URL)
aws ivs create-playback-key-pair \
--name my-playback-key \
--tags Key=Environment,Value=Production
Web での再生(IVS Player)
<!DOCTYPE html>
<html>
<head>
<title>IVS Low-Latency Live Stream</title>
<style>
body { margin: 0; background: #1a1a1a; color: #fff; font-family: Arial, sans-serif; }
.container { max-width: 1200px; margin: 0 auto; padding: 20px; }
video { width: 100%; height: auto; background: #000; border-radius: 8px; }
.metadata-display { background: rgba(255, 255, 255, 0.1); padding: 15px; margin-top: 15px; border-radius: 8px; }
.chat-container { margin-top: 20px; height: 400px; background: #2a2a2a; border-radius: 8px; overflow: hidden; display: flex; flex-direction: column; }
.chat-messages { flex: 1; overflow-y: auto; padding: 10px; }
.chat-message { margin: 5px 0; padding: 8px; background: rgba(255, 255, 255, 0.05); border-left: 3px solid #ff6b35; border-radius: 4px; font-size: 14px; }
.chat-input { display: flex; gap: 10px; padding: 10px; border-top: 1px solid #444; }
.chat-input input { flex: 1; padding: 10px; background: #3a3a3a; color: #fff; border: none; border-radius: 4px; }
.chat-input button { padding: 10px 20px; background: #ff6b35; color: #fff; border: none; border-radius: 4px; cursor: pointer; }
</style>
</head>
<body>
<div class="container">
<h1>IVS Low-Latency Live Stream</h1>
<video id="video-player" playsinline autoplay muted></video>
<div class="metadata-display" id="metadata-display">
<strong>Timed Metadata:</strong>
<div id="metadata-content">Waiting for metadata...</div>
</div>
<div class="chat-container">
<div class="chat-messages" id="chat-messages"></div>
<div class="chat-input">
<input
type="text"
id="chat-input"
placeholder="Type your message..."
autocomplete="off"
>
<button onclick="sendChatMessage()">Send</button>
</div>
</div>
</div>
<!-- IVS Player SDK -->
<script src="https://player.live-video.net/1.26.0/amazon-ivs-player.min.js"></script>
<script>
const IVSPlayer = window.IVSPlayer;
const PlayerState = IVSPlayer.PlayerState;
const PlayerEventType = IVSPlayer.PlayerEventType;
// バックエンドからライブストリーム URL を取得
async function initializePlayer() {
try {
// 署名付き再生 URL をバックエンドから取得
const response = await fetch('/api/get-playback-url', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
channelArn: 'arn:aws:ivs:us-east-1:123456789012:channel/AbCdEfGh'
})
});
const data = await response.json();
const playbackUrl = data.playback_url;
// IVS Player インスタンス作成
if (IVSPlayer.isPlayerSupported) {
const player = IVSPlayer.create();
player.attachHTMLVideoElement(document.getElementById('video-player'));
// ライブストリーム読み込み
player.load(playbackUrl);
player.play();
// プレイヤーイベント
player.addEventListener(PlayerEventType.STATE_CHANGE, (e) => {
console.log('Player state:', e.state);
if (e.state === PlayerState.PLAYING) {
console.log('✓ Live stream started');
} else if (e.state === PlayerState.BUFFERING) {
console.log('Buffering...');
}
});
// Timed Metadata(タイムコード付きメタデータ)
player.addEventListener(PlayerEventType.TEXT_METADATA_CUE, (cue) => {
try {
const metadata = JSON.parse(cue.text);
handleTimedMetadata(metadata);
} catch (err) {
console.error('Error parsing metadata:', err);
}
});
// エラーハンドリング
player.addEventListener(PlayerEventType.ERROR, (err) => {
console.error('Player error:', err);
});
// チャット接続
connectToChat(data.channel_arn);
} else {
console.error('IVS Player not supported');
}
} catch (error) {
console.error('Initialization error:', error);
}
}
// Timed Metadata 処理(商品情報・投票・クイズ等)
function handleTimedMetadata(metadata) {
const display = document.getElementById('metadata-content');
if (metadata.type === 'product') {
// ライブショッピング: 商品情報表示
display.innerHTML = `
<strong>🛍️ Featured Product</strong>
<p>
Name: ${metadata.productName}<br>
Price: $${metadata.price}<br>
Discount: ${metadata.discount}%
</p>
<button onclick="purchaseProduct('${metadata.productId}')">Buy Now</button>
`;
} else if (metadata.type === 'poll') {
// 投票
display.innerHTML = `
<strong>📊 Live Poll</strong>
<p>${metadata.question}</p>
${metadata.options.map((opt, i) => `
<button onclick="votePoll(${i})">${opt} (${metadata.votes?.[i] || 0})</button>
`).join('')}
`;
} else if (metadata.type === 'announcement') {
// アナウンスメント
display.innerHTML = `
<strong>📢 Announcement</strong>
<p>${metadata.message}</p>
`;
}
}
// IVS Chat 接続
async function connectToChat(channelArn) {
try {
// チャットルーム作成(バックエンド)
const response = await fetch('/api/create-chat-session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
channelArn: channelArn,
userId: 'viewer-' + Math.random().toString(36).substr(2, 9),
userName: 'Viewer'
})
});
const { token, roomArn } = await response.json();
// WebSocket 接続
const ws = new WebSocket(
`wss://${roomArn.split(':')[5]}.ivschat.live-video.net`
);
ws.onopen = () => {
console.log('✓ Chat connected');
// 認証メッセージ送信
ws.send(JSON.stringify({
type: 'CONNECT',
token: token
}));
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.type === 'MESSAGE') {
addChatMessage(message.userDisplayName, message.content);
}
};
ws.onerror = (err) => console.error('Chat error:', err);
ws.onclose = () => console.log('Chat disconnected');
// グローバル WebSocket 参照(メッセージ送信用)
window.chatWs = ws;
} catch (error) {
console.error('Chat connection error:', error);
}
}
// チャットメッセージ送信
function sendChatMessage() {
const input = document.getElementById('chat-input');
const message = input.value.trim();
if (message && window.chatWs) {
window.chatWs.send(JSON.stringify({
type: 'SEND_MESSAGE',
content: message
}));
input.value = '';
}
}
// チャットメッセージ表示
function addChatMessage(userName, content) {
const messagesDiv = document.getElementById('chat-messages');
const messageEl = document.createElement('div');
messageEl.className = 'chat-message';
messageEl.innerHTML = `<strong>${userName}:</strong> ${escapeHtml(content)}`;
messagesDiv.appendChild(messageEl);
messagesDiv.scrollTop = messagesDiv.scrollHeight;
}
function escapeHtml(text) {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return text.replace(/[&<>"']/g, m => map[m]);
}
function purchaseProduct(productId) {
alert('Product ' + productId + ' added to cart!');
}
function votePoll(optionIndex) {
console.log('Voted for option:', optionIndex);
}
// ページロード時に初期化
document.addEventListener('DOMContentLoaded', initializePlayer);
// Enter キーでメッセージ送信
document.getElementById('chat-input')?.addEventListener('keypress', (e) => {
if (e.key === 'Enter') sendChatMessage();
});
</script>
</body>
</html>
バックエンド API(Python FastAPI)
import boto3
import json
from datetime import datetime, timedelta
from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse
import hmac
import hashlib
import base64
app = FastAPI()
ivs_client = boto3.client('ivs', region_name='us-east-1')
ivs_chat_client = boto3.client('ivschat', region_name='us-east-1')
lambda_client = boto3.client('lambda')
# Playback Authorization キー(署名付き再生 URL 生成用)
PLAYBACK_KEY_ARN = 'arn:aws:ivs:us-east-1:123456789012:playback-key-pair/xxxxx'
PLAYBACK_KEY_PRIVATE = """-----BEGIN RSA PRIVATE KEY-----
... (秘密鍵の内容)
-----END RSA PRIVATE KEY-----"""
@app.post('/api/get-playback-url')
async def get_playback_url(channel_arn: str):
"""署名付き再生 URL を生成"""
try:
# チャンネル情報取得
response = ivs_client.get_channel(arn=channel_arn)
channel = response['channel']
playback_url_base = channel['playbackUrl']
# Playback Authorization が有効か確認
if channel.get('authorized'):
# JWT トークンを生成(署名付き再生 URL)
expiration = int((datetime.now() + timedelta(hours=24)).timestamp())
# Playback Authorization トークン生成
payload = {
'sub': 'user-demo',
'exp': expiration,
'iat': int(datetime.now().timestamp()),
'aws:channel-arn': channel_arn
}
# 実際には AWS Lambda で署名生成することを推奨
token = generate_playback_token(payload)
playback_url = f"{playback_url_base}?token={token}"
else:
playback_url = playback_url_base
return JSONResponse({
'success': True,
'playback_url': playback_url,
'channel_arn': channel_arn,
'playback_url_base': playback_url_base,
'latency_mode': channel.get('latencyMode')
})
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post('/api/put-metadata')
async def put_metadata(channel_arn: str, metadata: dict):
"""Timed Metadata をライブストリームに埋め込む"""
try:
# メタデータが有効か検証
metadata_json = json.dumps(metadata)
# IVS へメタデータ送信
ivs_client.put_metadata(
ChannelArn=channel_arn,
Metadata=metadata_json
)
return JSONResponse({
'success': True,
'metadata_type': metadata.get('type'),
'timestamp': datetime.now().isoformat()
})
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post('/api/create-chat-session')
async def create_chat_session(channel_arn: str, user_id: str, user_name: str):
"""IVS Chat セッション作成"""
try:
# チャットルーム作成(存在しない場合)
# 実装では Channel ARN から Chat Room ARN を導出
room_arn = channel_arn.replace(':channel/', ':room/')
# チャット認証トークン生成
token_response = ivs_chat_client.create_chat_token(
RoomIdentifier=room_arn,
UserId=user_id,
Capabilities=['SEND_MESSAGE', 'DELETE_MESSAGE'],
SessionDurationInMinutes=480, # 8 時間
Attributes={
'username': user_name,
'user_type': 'viewer',
'moderator': 'false'
}
)
return JSONResponse({
'success': True,
'token': token_response['Token'],
'roomArn': room_arn,
'tokenExpiration': token_response['TokenExpiration']
})
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post('/api/moderate-message')
async def moderate_message(room_arn: str, message_id: str, action: str):
"""チャットメッセージモデレーション(削除)"""
try:
if action == 'DELETE':
ivs_chat_client.delete_message(
RoomIdentifier=room_arn,
Id=message_id
)
return JSONResponse({'success': True})
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
def generate_playback_token(payload: dict) -> str:
"""Playback Authorization トークン生成(簡略版)"""
# 本番環境では AWS Signature Version 4 で署名
import jwt
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
key = serialization.load_pem_private_key(
PLAYBACK_KEY_PRIVATE.encode(),
password=None,
backend=default_backend()
)
token = jwt.encode(payload, key, algorithm='RS256')
return token
IVS Real-Time Streaming(WebRTC ベース)
# ホスト・視聴者が同時参加する低遅延ステージ
import boto3
from fastapi import FastAPI
app = FastAPI()
ivs_realtime = boto3.client('ivs-realtime', region_name='us-east-1')
@app.post('/api/create-stage')
async def create_stage(stage_name: str):
"""ステージ作成(最大 12 ホスト + 10,000 視聴者)"""
try:
response = ivs_realtime.create_stage(
name=stage_name,
participantTokenConfiguration={
'Capabilities': ['PUBLISH', 'SUBSCRIBE'],
'Duration': 14400 # 4 時間
}
)
return {
'success': True,
'stage_arn': response['stage']['arn'],
'stage_id': response['stage']['stageId']
}
except Exception as e:
return {'success': False, 'error': str(e)}
@app.post('/api/create-participant-token')
async def create_participant_token(
stage_arn: str,
user_id: str,
user_type: str # 'host' or 'viewer'
):
"""参加者トークン生成"""
try:
capabilities = []
if user_type == 'host':
capabilities = ['PUBLISH', 'SUBSCRIBE'] # ホスト: 配信 + 受信
else:
capabilities = ['SUBSCRIBE'] # 視聴者: 受信のみ
response = ivs_realtime.create_participant_token(
stageArn=stage_arn,
userId=user_id,
Capabilities=capabilities,
Duration=14400
)
return {
'success': True,
'token': response['participantToken']['token'],
'expiration': response['participantToken']['expirationTime']
}
except Exception as e:
return {'success': False, 'error': str(e)}
@app.get('/api/stage-events/{stage_arn}')
async def get_stage_events(stage_arn: str):
"""ステージイベント取得(参加者の出入り)"""
try:
response = ivs_realtime.list_stage_events(
stageArn=stage_arn,
maxResults=50
)
return {
'events': response.get('events', []),
'next_token': response.get('nextToken')
}
except Exception as e:
return {'error': str(e)}
Lambda メッセージモデレーション
# IVS Chat のメッセージを自動検査(不適切な内容を削除)
def message_review_handler(event, context):
"""
IVS Chat メッセージレビューハンドラー
event:
{
"roomArn": "arn:aws:ivschat:...",
"messageId": "msg-123456",
"sender": {"userId": "user-001"},
"message": {"content": "..."},
"timestamp": 1234567890
}
"""
message_content = event['message']['content']
# 1. 不適切な言葉フィルター(カスタム辞書)
banned_words = [
'badword1', 'badword2', 'spam_keyword'
]
for word in banned_words:
if word.lower() in message_content.lower():
return {
'result': 'DELETE' # メッセージ削除
}
# 2. URL スパム検出
import re
url_pattern = r'https?://[^\s]+'
urls = re.findall(url_pattern, message_content)
if len(urls) > 2:
return {'result': 'DELETE'}
# 3. キャップスロック過多(大文字ばかり)
uppercase_ratio = sum(1 for c in message_content if c.isupper()) / max(len(message_content), 1)
if uppercase_ratio > 0.8:
return {'result': 'DELETE'}
# 4. 過度なリピート
if len(set(message_content)) < len(message_content) * 0.1:
return {'result': 'DELETE'}
# OK
return {
'result': 'ALLOW'
}
料金体系(2026年)
| 項目 | 料金 | 備考 |
|---|---|---|
| ライブ配信(STANDARD) | $0.20/時間/配信 | インジェスト時間 |
| 視聴(HD 1080p) | $0.0025/GB | ダウンロード GB |
| 視聴(SD 480p) | $0.0015/GB | 低帯域向け |
| Real-Time Streaming | $0.0042/分/参加者 | ホスト・視聴者含む |
| IVS Chat | $0.20/千メッセージ | メッセージ数ベース |
| Recording(Live-to-VOD) | $0.005/分 | S3 保存料金別途 |
比較: IVS vs 競合
| 観点 | IVS | Twitch | YouTube Live | Wowza Streaming Cloud |
|---|---|---|---|---|
| 遅延 | 300ms 以下 | 2-30 秒 | 5-30 秒 | 2-15 秒 |
| インタラクション | ✓ タイムドメタデータ・Chat | 限定 | Chat のみ | 限定 |
| Real-Time Streaming | ✓ WebRTC(<300ms) | × | × | × |
| 価格 | 従量課金(低コスト) | 収益シェア | 収益シェア | 月額 $15-199 |
| カスタマイズ | ✓ API 完全開放 | × | × | ✓ |
| 独立配信 | ✓ | × | 要 YouTube Partner | ✓ |
| 推奨用途 | ライブショッピング・イベント | ゲーム配信 | 大規模配信 | 放送品質 |
ベストプラクティス
1. インジェスト設定(OBS)
Server: rtmps://a1bcdef34ghij.global-contribute.live-video.net:443/app/
Stream Key: sk_xxxxx
Video Bitrate: 4000 kbps (1080p/30fps)
Audio Bitrate: 128 kbps
Encoder: H.264 (x264)
2. Timed Metadata 設計
{
"type": "product",
"productId": "SKU-12345",
"productName": "Limited Edition Gaming Headset",
"price": 199.99,
"discount": 15,
"link": "https://shop.example.com/product/SKU-12345"
}
3. チャット モデレーション
- 自動フィルター: Lambda で不適切用語・スパム自動削除
- 手動モデレーション: Dashboard で リアルタイム監視・メッセージ削除
- ユーザーレート制限: 1秒 5 メッセージまで(デフォルト)
4. Real-Time 用ネットワーク
- 上りネット: 最小 2.5 Mbps(ホスト)、0.5 Mbps(視聴者)
- 下りネット: 最小 5 Mbps(ホスト・視聴者共通)
- 遅延目標: <500ms LAN、<2s インターネット
設計チェックリスト
- [ ] Channel 作成済み・latency mode = ULTRA_LOW(300ms)
- [ ] Stream Key を安全に配布(環境変数・シークレットマネージャー)
- [ ] Recording Configuration 設定済み(S3 버킷)
- [ ] Playback Authorization キーペア生成済み(署名付き再生 URL)
- [ ] IVS Player SDK で HLS 再生・Timed Metadata 受信実装済み
- [ ] IVS Chat で WebSocket 接続・メッセージ送受信実装済み
- [ ] Lambda メッセージレビューハンドラー デプロイ済み
- [ ] CloudWatch でインジェストビットレート・視聴者数監視中
- [ ] Real-Time Streaming(Stage)テスト完了(WebRTC <300ms)
- [ ] DDoS: CloudFront WAF + Shield Standard 有効化
- [ ] コスト: 月間推定出力 GB・メッセージ数から費用試算済み
実装パターン: ライブショッピング
要件: 1時間のライブ配信・商品メタデータ同期・リアルタイムチャット・1000 同時視聴者
# バックエンド: Flask + Celery
from flask import Flask, request, jsonify
from celery import Celery
import boto3
app = Flask(__name__)
ivs = boto3.client('ivs', region_name='us-east-1')
celery_app = Celery(app.name)
# ライブ配信セッション管理
live_sessions = {}
@app.post('/api/start-live-shopping')
def start_live_shopping():
"""ライブショッピング配信開始"""
channel_arn = 'arn:aws:ivs:us-east-1:123456789012:channel/LiveShop'
# 配信情報を DynamoDB に保存
session_id = f"session-{int(time.time())}"
live_sessions[session_id] = {
'channel_arn': channel_arn,
'start_time': datetime.now(),
'status': 'LIVE',
'products': []
}
return jsonify({'session_id': session_id, 'status': 'started'})
@app.post('/api/feature-product')
def feature_product():
"""商品をライブ配信に同期"""
data = request.json
session_id = data['session_id']
product = {
'id': data['product_id'],
'name': data['product_name'],
'price': data['price'],
'discount': data.get('discount', 0),
'image_url': data['image_url']
}
# Timed Metadata で配信に埋め込む
send_metadata_task.delay(
live_sessions[session_id]['channel_arn'],
{
'type': 'product',
'productId': product['id'],
'productName': product['name'],
'price': product['price'],
'discount': product['discount'],
'imageUrl': product['image_url']
}
)
return jsonify({'success': True})
@celery_app.task
def send_metadata_task(channel_arn, metadata):
"""メタデータ送信タスク"""
try:
ivs.put_metadata(
ChannelArn=channel_arn,
Metadata=json.dumps(metadata)
)
return {'success': True}
except Exception as e:
return {'error': str(e)}
@app.post('/api/end-live-shopping')
def end_live_shopping():
"""ライブ配信終了"""
session_id = request.json['session_id']
# セッション終了(S3 に自動記録)
live_sessions[session_id]['status'] = 'ENDED'
live_sessions[session_id]['end_time'] = datetime.now()
return jsonify({'success': True})
@app.get('/api/live-metrics/{session_id}')
def get_live_metrics(session_id):
"""ライブ配信メトリクス取得"""
channel_arn = live_sessions[session_id]['channel_arn']
response = ivs.get_stream(
ChannelArn=channel_arn
)
stream = response.get('stream')
if stream:
return jsonify({
'viewers': stream.get('viewerCount', 0),
'health': stream.get('health', {}),
'ingest_bitrate': stream.get('health', {}).get('bitrate'),
'encoding': stream.get('health', {}).get('encoding')
})
return jsonify({'error': 'No active stream'})
最新動向(2024-2026)
- Real-Time Streaming 拡張: WebRTC ベースの <300ms ストリーミング実装完了(2024)
- IVS Chat 統計: メッセージ分析・視聴者エンゲージメント追跡機能(2025)
- AI モデレーション: 機械学習ベースの不適切コンテンツ自動検出(2026 予定)
- Dolby Atmos: サラウンドサウンド配信対応(検討中)
まとめ
Amazon IVS は 「超低遅延(300ms)のインタラクティブライブストリーミングプラットフォーム」。Twitch 技術ベースの信頼性・タイムドメタデータによるライブショッピング・IVS Chat と Real-Time Streaming を統合し、リアルタイム双方向体験を実現。
ライブショッピング・ゲーム配信・バーチャルイベント・オークション等の B2C インタラクティブアプリケーションに最適。マネージドサービスで インフラ管理不要、従量課金で低コスト。