LIVE
กำลังโหลด...
📡 API & Stream Code Examples
// ==========================================
// Naver Sports API - Today's Games
// ==========================================

// 1. ดึงตารางแข่งวันนี้
const API_URL = 'https://api-gw.sports.naver.com/schedule/today-games';
const FIELDS = 'basic,superCategoryId,categoryName,upperCategoryId,upperCategoryName,stadium,statusNum,gameOnAir,hasVideo,title,specialMatchInfo,roundCode,seriesOutcome,seriesGameNo,timeTbd,homeStarterName,awayStarterName,winPitcherName,losePitcherName,homeCurrentPitcherName,awayCurrentPitcherName,broadChannel,matchRound,roundTournamentInfo,phaseCode,groupName,leg,hasPtSore,homePtScore,awayPtScore,league,leagueName,aggregateWinner,neutralGround,postponed,conference,round,groupName,round,generalInfo3,manualRelayUrl,tennis,ufc';

async function fetchTodayGames() {
  const res = await fetch(`${API_URL}?fields=${FIELDS}`);
  const data = await res.json();
  return data.result.games; // Array of game objects
}

// ==========================================
// Live Stream Links (manualRelayUrl = Chzzk)
// ==========================================

function getStreamLinks(game) {
  const links = [];

  // Chzzk (NAVER) livestream
  if (game.manualRelayUrl) {
    links.push({ type: 'chzzk', url: game.manualRelayUrl });
  }

  // Extract Chzzk stream ID
  if (game.manualRelayUrl?.includes('chzzk.naver.com/live/')) {
    const channelId = game.manualRelayUrl.split('chzzk.naver.com/live/')[1]?.split('?')[0];
    // Fetch m3u8 via Chzzk API
    links.push({ type: 'm3u8_api', url: `https://api.chzzk.naver.com/service/v2/channels/${channelId}/live-detail` });
  }

  // Broadcast channel (TV)
  if (game.broadChannel) {
    links.push({ type: 'broadcast', channel: game.broadChannel });
  }

  return links;
}

// ==========================================
// Fetch Chzzk M3U8 Stream URL
// ==========================================

async function getChzzkM3U8(channelId) {
  const res = await fetch(
    `https://api.chzzk.naver.com/service/v2/channels/${channelId}/live-detail`,
    { headers: { 'User-Agent': 'Mozilla/5.0' } }
  );
  const data = await res.json();
  const livePlayback = JSON.parse(data?.content?.livePlaybackJson || '{}');

  // Extract HLS m3u8
  const hlsMedia = livePlayback?.media?.find(m => m.mediaId === 'HLS');
  return hlsMedia?.path; // → "https://.../.m3u8"
}

// ==========================================
// Full Example: Get All Live Games + Streams
// ==========================================

async function getLiveGamesWithStreams() {
  const games = await fetchTodayGames();

  const liveGames = games.filter(g =>
    g.statusCode === 'STARTED' && g.manualRelayUrl
  );

  const withStreams = await Promise.all(liveGames.map(async game => {
    const channelMatch = game.manualRelayUrl?.match(
      /chzzk\.naver\.com\/(?:live\/)?([a-f0-9]+)/
    );
    let m3u8 = null;
    if (channelMatch) {
      m3u8 = await getChzzkM3U8(channelMatch[1]);
    }
    return { ...game, m3u8 };
  }));

  return withStreams;
}

// ==========================================
// Play M3U8 with HLS.js
// ==========================================

// <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
function playM3U8(m3u8Url, videoElement) {
  if (Hls.isSupported()) {
    const hls = new Hls();
    hls.loadSource(m3u8Url);
    hls.attachMedia(videoElement);
  } else if (videoElement.canPlayType('application/vnd.apple.mpegurl')) {
    videoElement.src = m3u8Url; // Safari native HLS
  }
}

// ==========================================
// Game Status Codes
// BEFORE = ยังไม่เริ่ม | STARTED = กำลังแข่ง
// RESULT = จบแล้ว     | cancel = ยกเลิก
// ==========================================