将 youtube API v3 视频持续时间转换为 php


Convert youtube Api v3 video duration in php

如何将PT2H34M25S转换为 2:34:25

我搜索并使用了这个代码。我是正则表达式的新手,有人可以解释一下吗?并帮助我解决我的问题

function covtime($youtube_time){
        preg_match_all('/('d+)/',$youtube_time,$parts);
        $hours = floor($parts[0][0]/60);
        $minutes = $parts[0][0]%60;
        $seconds = $parts[0][1];
        if($hours != 0)
            return $hours.':'.$minutes.':'.$seconds;
        else
            return $minutes.':'.$seconds;
    }   

但是这段代码只给了我HH:MM

所以哑巴找到了解决方案:

   function covtime($youtube_time){
            preg_match_all('/('d+)/',$youtube_time,$parts);
            $hours = $parts[0][0];
            $minutes = $parts[0][1];
            $seconds = $parts[0][2];
            if($seconds != 0)
                return $hours.':'.$minutes.':'.$seconds;
            else
                return $hours.':'.$minutes;
        }

使用 DateTime 类

您可以使用PHP的DateTime类来实现此目的。此解决方案要简单得多,即使字符串中数量的格式顺序不同,也可以工作。在这种情况下,正则表达式解决方案(很可能(会中断。

在 PHP 中,PT2H34M25S 是一个有效的日期周期字符串,由 DateTime 解析器理解。然后我们利用这个事实,并使用add()方法将其添加到 Unix 时代。然后,您可以设置结果日期的格式以获得所需的结果:

function covtime($youtube_time){
    if($youtube_time) {
        $start = new DateTime('@0'); // Unix epoch
        $start->add(new DateInterval($youtube_time));
        $youtube_time = $start->format('H:i:s');
    }
    
    return $youtube_time;
}   
echo covtime('PT2H34M25S');

演示

AmalPferate的解决方案都很棒!但是,Amal 解决方案继续给我额外的 1 小时。以下是我的解决方案,它与 Amal 相同,但方法不同,这对我有用。

$date = new DateTime('1970-01-01');
$date->add(new DateInterval('PT2H34M25S'));
echo $date->format('H:i:s')

datetime->add()参考

资料
这是我

处理丢失的H,M或S的解决方案(测试报告长度为1:00:01的视频,您将看到其他答案的问题(。秒单独显示为 0:01,但如果您想更改它,只需将最后一个 else 更改为 elseif($M>0) 并添加秒的 else,例如 else { return ":$S" }

// convert youtube v3 api duration e.g. PT1M3S to HH:MM:SS
// updated to handle videos days long e.g. P1DT1M3S
function covtime($yt){
    $yt=str_replace(['P','T'],'',$yt);
    foreach(['D','H','M','S'] as $a){
        $pos=strpos($yt,$a);
        if($pos!==false) ${$a}=substr($yt,0,$pos); else { ${$a}=0; continue; }
        $yt=substr($yt,$pos+1);
    }
    if($D>0){
        $M=str_pad($M,2,'0',STR_PAD_LEFT);
        $S=str_pad($S,2,'0',STR_PAD_LEFT);
        return ($H+(24*$D)).":$M:$S"; // add days to hours
    } elseif($H>0){
        $M=str_pad($M,2,'0',STR_PAD_LEFT);
        $S=str_pad($S,2,'0',STR_PAD_LEFT);
        return "$H:$M:$S";
    } else {
        $S=str_pad($S,2,'0',STR_PAD_LEFT);
        return "$M:$S";
    }
}
创建

$parts变量后,您应该查看它。

var_dump($parts);

将该输出与定义变量的方式进行比较。 在那之后,它应该非常明显地脱颖而出。

我想我之后的下一个问题是你期待输入时间字符串的哪些变化,你将进行什么验证? 要处理的输入格式的变化将影响实际编写代码的复杂性。

编辑:这是一个更新的函数,用于处理缺失的数值(如果省略小时或分钟(和超过 60 的秒/小时(不确定这是否会发生(。 这不会验证数字的标签:

  • 1 个数字:假设是秒
  • 2 个数字:假设是分钟、秒
  • 3
  • 个或更多数字:假设前 3 个数字是小时、分钟、秒(忽略另一个数字(

可以添加更多验证来研究验证输入字符串。

<?php
function covtime($youtube_time) {
    preg_match_all('/('d+)/',$youtube_time,$parts);
    // Put in zeros if we have less than 3 numbers.
    if (count($parts[0]) == 1) {
        array_unshift($parts[0], "0", "0");
    } elseif (count($parts[0]) == 2) {
        array_unshift($parts[0], "0");
    }
    $sec_init = $parts[0][2];
    $seconds = $sec_init%60;
    $seconds_overflow = floor($sec_init/60);
    $min_init = $parts[0][1] + $seconds_overflow;
    $minutes = ($min_init)%60;
    $minutes_overflow = floor(($min_init)/60);
    $hours = $parts[0][0] + $minutes_overflow;
    if($hours != 0)
        return $hours.':'.$minutes.':'.$seconds;
    else
        return $minutes.':'.$seconds;
}
这是我

的解决方案,测试完成!

preg_match_all("/PT('d+H)?('d+M)?('d+S)?/", $duration, $matches);
$hours   = strlen($matches[1][0]) == 0 ? 0 : substr($matches[1][0], 0, strlen($matches[1][0]) - 1);
$minutes = strlen($matches[2][0]) == 0 ? 0 : substr($matches[2][0], 0, strlen($matches[2][0]) - 1);
$seconds = strlen($matches[3][0]) == 0 ? 0 : substr($matches[3][0], 0, strlen($matches[3][0]) - 1);
return 3600 * $hours + 60 * $minutes + $seconds;

我使用两个类,一个用于调用YouTube API,一个用于转换时间。 这里被简化。

如您所见,YouTubeGet 是一个静态类,但并非必须如此。 然而,YouTubeDateInterval必须是一个实例,因为DateInterval的工作方式(正在扩展(。

class YouTubeGet{
static public function get_duration($video_id, $api_key){
        // $youtube_api_key
        $url = "https://www.googleapis.com/youtube/v3/videos?id={$video_id}&part=contentDetails&key={$api_key}";
        // Get and convert. This example uses wordpress wp_remote_get()
        // this could be replaced by file_get_contents($url);
        $response = wp_remote_get($url);
        // if using file_get_contents(), then remove ['body']
        $result = json_decode($response['body'], true);
        // I've converted to an array, but this works fine as an object
        if(isset($result['items'][0]['contentDetails']['duration'])){
            $duration = $result['items'][0]['contentDetails']['duration'];
            return self::convtime($duration);
        }
        return false;
    }
    static protected function convtime($youtube_time){
        $time = new YouTubeDateInterval($youtube_time);        
        return $time->to_seconds();
    }   
}
class YouTubeDateInterval extends DateInterval {
    public function to_seconds() 
      { 
        return ($this->y * 365 * 24 * 60 * 60) + 
               ($this->m * 30 * 24 * 60 * 60) + 
               ($this->d * 24 * 60 * 60) + 
               ($this->h * 60 * 60) + 
               ($this->i * 60) + 
               $this->s; 
      } 
}

用法是将 ISO 8601 日期传递给 YouTubeDateInterval。

$time = new YouTubeDateInterval('PT2H34M25S');
$duration_in_seconds = $time->to_seconds();

或传递 YouTube 获取 API 和视频 ID 密钥

$duration_in_seconds = YouTubeGet::get_duration('videoIdString','YouTubeApiKeyString');

这是获取,转换和显示视频持续时间的完整代码

$vidkey = "           " ; // for example: cHPMH26sw2f
$apikey = "xxxxxxxxxxxx" ;
$dur = file_get_contents("https://www.googleapis.com/youtube/v3/videos?part=contentDetails&id=$vidkey&key=$apikey");
$VidDuration =json_decode($dur, true);
foreach ($VidDuration['items'] as $vidTime) 
{
$VidDuration= $vidTime['contentDetails']['duration'];
}
// convert duration from ISO to M:S
$date = new DateTime('2000-01-01');
$date->add(new DateInterval($VidDuration));
echo $date->format('i:s') ;

将 xxxxxxx 替换为您的 API 密钥结果:13:07

试试这个会给你的持续时间几秒钟

function video_length($youtube_time)
{
    $duration = new 'DateInterval($youtube_time);
    return $duration->h  * 3600 + $duration->i  * 60  + $duration->s;
}
$duration = new 'DateInterval($data['items'][0]['contentDetails']['duration']);
echo $duration->format('%H:%i:%s');
function getDuration($duration): string
{
    preg_match_all("/P('d+D)?T('d+H)?('d+M)?('d+S)?/", $duration, $m);
    $days = empty($m[1][0]) ? 0 : substr($m[1][0], 0, -1);
    $hours = empty($m[2][0]) ? 0 : substr($m[2][0], 0, -1);
    $minutes = empty($m[3][0]) ? 0 : substr($m[3][0], 0, -1);
    $seconds = empty($m[4][0]) ? 0 : substr($m[4][0], 0, -1);
    $hours += ($days * 24);
    $hours = sprintf("%02d", $hours);
    $minutes = sprintf("%02d", $minutes);
    $seconds = sprintf("%02d", $seconds);
    return "$hours:$minutes:$seconds";
}

例:

input: PT2H34M25S
output: 02:34:25
input: P1DT3H12M8S
output: 27:12:08

我已经通过使用use Carbon'CarbonInterval库完成了此操作。

public static function convert_youtube_duration_to_normal(string $youtube_time)
{
    return CarbonInterval::create($youtube_time)->forHumans();
}

Functions::convert_youtube_duration_to_normal('PT4M25S')

作为输出返回"4 minutes 25 seconds"

尝试以下函数:

function covtime($youtube_time) 
{
    $hours = '0';
    $minutes = '0';
    $seconds = '0';
    $hIndex = strpos($youtube_time, 'H');
    $mIndex = strpos($youtube_time, 'M');
    $sIndex = strpos($youtube_time, 'S');
    $length = strlen($youtube_time);
    if($hIndex > 0)
    {
        $hours = substr($youtube_time, 2, ($hIndex - 2));
    }
    if($mIndex > 0)
    {
        if($hIndex > 0)
        {
            $minutes = substr($youtube_time, ($hIndex + 1), ($mIndex - ($hIndex + 1)));
        }      
        else
        {
            $minutes = substr($youtube_time, 2, ($mIndex - 2));
        }
    }
    if($sIndex > 0)
    {
        if($mIndex > 0)
        {
            $seconds = substr($youtube_time, ($mIndex + 1), ($sIndex - ($mIndex + 1)));
        }
        else if($hIndex > 0)
        {
            $seconds = substr($youtube_time, ($hIndex + 1), ($sIndex - ($hIndex + 1)));
        }      
        else
        {
            $seconds = substr($youtube_time, 2, ($sIndex - 2));
        }
    }
    return $hours.":".$minutes.":".$seconds;        
}

你可以试试这个 -

function covtime($youtube_time){
    $start = new DateTime('@0'); // Unix epoch
    $start->add(new DateInterval($youtube_time));
    if (strlen($youtube_time)>8)
    {
    return $start->format('g:i:s');
}   else {
	return $start->format('i:s');
}
}

DateTime 和 DateInterval 在 Yii 或某些 php 版本中不起作用。这就是我的解决方案。它与我一起工作。

function convertTime($time){        
    if ($time > 0){
        $time_result = '';
        $hours = intval($time / 3600);
        if ($hours > 0)
            $time_result = $time_result.$hours.':';
        $time = $time % 3600;
        $minutes = intval($time / 60);
        $seconds = $time % 60;
        $time_result = $time_result.(($minutes > 9)?$minutes:'0'.$minutes).':';
        $time_result = $time_result.(($seconds > 9)?$seconds:'0'.$seconds);
    }else 
        $time_result = '0:00';        
    return $time_result;
}

为什么会变得复杂。跳出框框思考。

    $seconds = substr(stristr($length, 'S', true), -2, 2);
    $seconds = preg_replace("/[^0-9]/", '', $seconds);
    $minutes =  substr(stristr($length, 'M', true), -2, 2);
    $minutes = preg_replace("/[^0-9]/", '', $minutes);
    $hours =  substr(stristr($length, 'H', true), -2, 2);
    $hours = preg_replace("/[^0-9]/", '', $hours);

好的。preg_replace并不是真的需要的,但我把它放在保证数字上。

然后对于我的格式(您可以无限制地随心所欲地做(,

      if($hours == 0){ 
      $h= '';
      }else{ 
      $h= $hours.':';
      }
      if($minutes <10){ 
      $m= '0'.$minutes.':'; 
        if($h == ''){
        $m= $minutes.':'; 
        }
          if ($minutes == 0){
            $m= $minutes;                 
          }
      }else{ 
      $m= $minutes.':';
      }
      if($seconds <10){ 
      $s= '0'.$seconds; 
      }else{ 
      $s= $seconds;
      }
      $time= $h . $m . $s.'s';