PHP如何獲取HLS流媒體信息 HLS流媒體信息獲取教程

php獲取hls流媒體信息需先解析.m3u8文件。1. 使用file_get_contents()讀取m3u8文件內容;2. 通過explode()逐行解析文本;3. 提取關鍵標簽如#ext-x-version、#ext-x-media-sequence、#ext-x-targetduration及#extinf等;4. 處理相對url轉換為絕對路徑;5. 若存在aes-128加密,解析#ext-x-key獲取密鑰url并解密媒體片段;6. 針對多碼率流,識別#ext-x-stream-inf標簽并遞歸解析不同碼率的m3u8文件;7. 性能優化方面采用流式讀取、正則表達式優化、緩存解析結果及高效字符串處理函數以提升效率。

PHP如何獲取HLS流媒體信息 HLS流媒體信息獲取教程

PHP獲取HLS流媒體信息,核心在于解析HLS的索引文件(.m3u8文件)。這文件里包含了視頻分片和其他必要信息,我們可以用PHP讀取并處理它。

PHP如何獲取HLS流媒體信息 HLS流媒體信息獲取教程

解決方案:

PHP如何獲取HLS流媒體信息 HLS流媒體信息獲取教程

  1. 讀取M3U8文件內容

使用file_get_contents()函數讀取M3U8文件的URL,將其內容保存到字符串中。

立即學習PHP免費學習筆記(深入)”;

PHP如何獲取HLS流媒體信息 HLS流媒體信息獲取教程

<?php $m3u8_url = 'YOUR_M3U8_URL'; $m3u8_content = file_get_contents($m3u8_url);  if ($m3u8_content === false) {     die('Failed to fetch M3U8 file.'); }  // 現在 $m3u8_content 包含了 M3U8 文件的內容 ?>
  1. 解析M3U8內容

M3U8文件是文本文件,我們需要逐行解析。使用explode()函數按行分割字符串。

<?php $lines = explode("n", $m3u8_content); ?>
  1. 提取關鍵信息

遍歷每一行,根據M3U8文件的格式提取信息。常見的標簽包括:

  • #EXTM3U: 文件頭,表示這是一個M3U8文件。
  • #EXT-X-VERSION: HLS協議版本。
  • #EXT-X-MEDIA-SEQUENCE: 第一個媒體片段的序列號。
  • #EXT-X-TARGETDURATION: 每個媒體片段的目標持續時間(秒)。
  • #EXTINF: 媒體片段的信息,包括持續時間和文件名。
  • #EXT-X-ENDLIST: 表示流的結束。
<?php $version = null; $media_sequence = null; $target_duration = null; $segments = [];  foreach ($lines as $line) {     $line = trim($line); // 去除空白      if (strpos($line, '#EXT-X-VERSION') === 0) {         $version = intval(substr($line, strlen('#EXT-X-VERSION:')));     } elseif (strpos($line, '#EXT-X-MEDIA-SEQUENCE') === 0) {         $media_sequence = intval(substr($line, strlen('#EXT-X-MEDIA-SEQUENCE:')));     } elseif (strpos($line, '#EXT-X-TARGETDURATION') === 0) {         $target_duration = intval(substr($line, strlen('#EXT-X-TARGETDURATION:')));     } elseif (strpos($line, '#EXTINF') === 0) {         // 獲取片段持續時間         preg_match('/EXTINF:([d.]+)/', $line, $matches);         $duration = floatval($matches[1]);          // 獲取片段文件名 (下一行)         $segment_url = trim(next($lines));         $segments[] = ['duration' => $duration, 'url' => $segment_url];     } elseif (strpos($line, '#EXT-X-STREAM-INF') === 0) {         //處理多碼率情況,提取不同碼率的url         preg_match('/URI="([^"]+)"/', $line, $matches);         if(isset($matches[1])){             $variant_url = $matches[1];             //這里可以遞歸調用這個函數,解析不同碼率的m3u8文件         }      } }  // 現在你可以使用這些信息了 var_dump($version, $media_sequence, $target_duration, $segments); ?>
  1. 處理相對URL

如果媒體片段的URL是相對路徑,需要將其轉換為絕對路徑。

<?php function makeAbsoluteUrl($base_url, $relative_url) {     // 使用PHP內置函數處理     return SabreUriresolve($base_url, $relative_url); }  $base_url = dirname($m3u8_url) . '/'; // M3U8文件所在的目錄 foreach ($segments as &$segment) {     $segment['url'] = makeAbsoluteUrl($base_url, $segment['url']); } ?>

如何處理M3U8文件中的加密內容(如AES-128)?

M3U8文件中可能包含加密信息,例如使用AES-128加密。 遇到這種情況,你需要:

  1. 查找密鑰URL:M3U8文件中會有一個#EXT-X-KEY標簽,其中包含密鑰的URL。

    #EXT-X-KEY:METHOD=AES-128,URI="YOUR_KEY_URL",IV=0x...
  2. 獲取密鑰:使用file_get_contents()從密鑰URL獲取密鑰。

  3. 解密媒體片段:使用OpenSSL或其他加密庫,使用密鑰和IV解密每個媒體片段。 這部分比較復雜,需要深入了解加密算法

<?php // 假設你已經獲取了密鑰和IV $key_url = 'YOUR_KEY_URL'; $key = file_get_contents($key_url);  //IV 一般在EXT-X-KEY中指定,如果沒有,則默認為0 $iv = 'YOUR_IV';  // 使用 openssl 解密 $encrypted_data = file_get_contents('YOUR_ENCRYPTED_TS_FILE'); $decrypted_data = openssl_decrypt($encrypted_data, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $iv);  if ($decrypted_data === false) {     echo "解密失敗: " . openssl_error_string() . "n"; } else {     // 保存解密后的數據     file_put_contents('YOUR_DECRYPTED_TS_FILE', $decrypted_data); } ?>

如何處理多碼率(Adaptive Bitrate Streaming)的M3U8文件?

多碼率HLS使用#EXT-X-STREAM-INF標簽來描述不同的碼率流。每個#EXT-X-STREAM-INF標簽后面跟著一個M3U8文件的URL,這個文件描述了特定碼率的流。

  1. 提取碼率信息:解析#EXT-X-STREAM-INF標簽,提取帶寬、分辨率等信息,以及對應的M3U8 URL。

  2. 選擇合適的碼率:根據網絡狀況和設備性能,選擇合適的碼率。

  3. 遞歸解析:下載并解析選定的M3U8文件,獲取媒體片段信息。

<?php // 在主循環中,處理 #EXT-X-STREAM-INF elseif (strpos($line, '#EXT-X-STREAM-INF') === 0) {     preg_match('/BANDWIDTH=(d+),.*URI="([^"]+)"/', $line, $matches);     $bandwidth = intval($matches[1]);     $variant_url = trim($matches[2]);      // 遞歸調用函數,解析不同碼率的m3u8文件     $variant_data = parseM3U8($variant_url);     $variants[] = ['bandwidth' => $bandwidth, 'url' => $variant_url, 'data' => $variant_data]; }  //輔助函數,遞歸解析不同碼率的m3u8文件 function parseM3U8($url){     $m3u8_content = file_get_contents($url);     //... 這里可以復用之前的解析邏輯     return $m3u8_content; } ?>

如何優化php解析M3U8文件的性能?

  • 使用流式讀取:file_get_contents會將整個文件讀入內存,對于大型M3U8文件,這可能會導致內存問題。可以使用fopenfgets等函數逐行讀取文件。
  • 使用正則表達式優化:雖然strpos和substr簡單易懂,但對于復雜的匹配,正則表達式可能更高效。
  • 緩存解析結果:如果M3U8文件不經常更新,可以將解析結果緩存到文件中或使用redis等緩存系統。
  • 避免重復計算:在循環中,避免重復計算字符串長度等值。
  • 使用更高效的字符串函數:根據實際情況,選擇更高效的字符串處理函數。 例如,strtok可能比explode更適合某些場景。

? 版權聲明
THE END
喜歡就支持一下吧
點贊10 分享