【问题标题】:Extract minutes and seconds (ex '02m12s') from YouTube URL param从 YouTube URL 参数中提取分钟和秒(例如“02m12s”)
【发布时间】:2012-07-05 19:14:00
【问题描述】:

从 youtube 网址中提取分钟和秒的最佳方法?

http://www.youtube.com/watch?v=TjTbNWhsG28#t=1m40s&foo=1&bar=2

1m40s 是我需要的字符串,可以使用 '#t=' 或 '&t='。

也可能在最后(或在中间,但不太可能。我会排除那个)

http://www.youtube.com/watch?v=TjTbNWhsG28?foo=1&bar=2#t=1m40s

“xmxs”中的“x”可以是一位或两位数,并且只能传递其中一个

"#t=10m3s" 或 "&t=09m12s"

它们都是可选的

"#t=10m" 或 "&t=3s" 或 "#t=10m03"s

YouTube 现在接受 '#t=' 和 '&t=' 作为这个参数,所以理想情况下我需要同时考虑这两个参数。用户将这些粘贴到博客的 cmets 部分,输出生成嵌入。我当前使用的脚本不会解析这些时间值。

一旦我知道了分钟和秒,我会将总秒数传递给使用“开始”参数生成嵌入代码的脚本。 https://developers.google.com/youtube/player_parameters#start

我需要一个 PHP 解决方案。我假设substr() 和正则表达式的完美结合。

【问题讨论】:

    标签: php regex string youtube


    【解决方案1】:

    使用这个正则表达式((#)|(\&))t=(\d+m)?(\d+s)?

    【讨论】:

    • Warning: preg_match_all(): Unknown modifier 't' in C:\wamp\www\php\yturl.php on line 6
    • @Nikola K., t 只是字符串中的符号,可能你失去了盾牌吗?
    • 正则表达式是正确的,但我不知道 php 可以帮助解决这个警告
    • 将正则表达式括在分隔符中,例如@((#)|(\&))t=(\d+m)?(\d+s)?@
    【解决方案2】:

    我发现已接受答案的代码非常混乱。它也不包括几个小时。我还认为 YouTube 放弃了 # 网址。我在我的Advanced Responsive Video Embedder WordPress 插件中编写了这个函数。与公认的答案相比,我认为它的代码非常简洁且更易于理解。

    我希望这会对某人有所帮助。

    2019 年更新通知 (int) 部分去除了 h/m/s 字符。我愿意提出改进建议。

    /**
     * Calculates seconds based on youtube times
     *
     * @author    Nicolas Jonas
     * @license   GPLv3
     * @link      http://nextgenthemes.com
     *
     * @param     string $yttime   The '1h25m13s' part of youtube URLs
     *
     * @return    int   Starttime in seconds
     */
    function youtube_time_to_seconds( $yttime ) {
    
        $matches['h'] = 0;
        $matches['m'] = 0;
        $matches['s'] = 0;
    
        $pattern = '/' .
            '(?<h>[0-9]+h)?' .
            '(?<m>[0-9]+m)?' .
            '(?<s>[0-9]+s)?/';
    
        preg_match( $pattern, $yttime, $matches );
    
        return ( (int) $matches['h'] * 60 * 60 ) +
            ( (int) $matches['m'] * 60 ) +
            (int) $matches['s'];
    }
    

    参考的旧代码。不考虑案例 1h2s:

    /**
     * Calculates seconds based on youtube times
     *
     * @author    Nicolas Jonas
     * @license   GPLv3
     * @link      http://nextgenthemes.com
     *
     * @param     string $yttime   The '1h25m13s' part of youtube URLs
     *
     * @return    int   Starttime in seconds
     */
    function youtube_time_to_seconds( $yttime ) {
    
        $format = false;
        $hours  = $minutes = $seconds = 0;
    
        $pattern['hms'] = '/([0-9]+)h([0-9]+)m([0-9]+)s/'; // hours, minutes, seconds
        $pattern['ms']  =          '/([0-9]+)m([0-9]+)s/'; // minutes, seconds
        $pattern['h']   = '/([0-9]+)h/';
        $pattern['m']   = '/([0-9]+)m/';
        $pattern['s']   = '/([0-9]+)s/';
    
        foreach ( $pattern as $k => $v ) {
    
            preg_match( $v, $yttime, $result );
    
            if ( ! empty( $result ) ) {
                $format = $k;
                break;
            }
        }
    
        switch ( $format ) {
            case 'hms':
                $hours   = $result[1];
                $minutes = $result[2];
                $seconds = $result[3];
                break;
            case 'ms':
                $minutes = $result[1];
                $seconds = $result[2];
                break;
            case 'h':
                $hours = $result[1];
                break;
            case 'm':
                $minutes = $result[1];
                break;
            case 's':
                $seconds = $result[1];
                break;
            default:
                return false;
        }
    
        return ( $hours * 60 * 60 ) + ( $minutes * 60 ) + $seconds;
    }
    

    来源:Github

    可以这样使用它:

    它使用 parse_urlparse_str 解析 URL 和参数,而不是正则表达式整个 URL,这是更好、更可靠的方法。

    $urls[] = 'http://youtu.be/vrXgLhkv21Y';
    $urls[] = 'http://youtu.be/vrXgLhkv21Y?t=foobar';
    $urls[] = 'http://youtu.be/vrXgLhkv21Y?foo=bar&t=4s';
    $urls[] = 'http://youtu.be/vrXgLhkv21Y?t=1h19m14s';
    $urls[] = 'http://youtu.be/vrXgLhkv21Y?t=19m14s';
    $urls[] = 'http://youtu.be/vrXgLhkv21Y?t=2h';
    $urls[] = 'http://youtu.be/vrXgLhkv21Y?t=5m';
    $urls[] = 'http://youtu.be/vrXgLhkv21Y?t=50s';
    
    #extract the part after the &t= in urls and run the function if exists 
    foreach( $urls as $url ) {
    
        $parsed_url = parse_url( $url );
    
        if ( empty( $parsed_url['query'] ) )
            continue;
    
        parse_str( $parsed_url['query'], $args );
    
        if ( empty( $args['t'] ) )
            continue;
    
        echo youtube_time_to_seconds( $args['t'] ) . "\n";
    }
    

    输出:

    4
    4754
    1154
    7200
    300
    50
    

    【讨论】:

    • 这很好,但是您错过了时间为 hmhs 格式的情况(例如:1h1m、1h10s,两者都有效。)您可以使用单个模式preg_match:'/([0-9]+h)?([0-9]+m)?([0-9]+s)?/' 捕获小时/分钟/秒。例如:$hours = array_key_exists( 1, $result ) ? $result[1] : 0;.
    • @FabienSnauwaert 你说得对,我添加了一个更简单的新功能,没有使用任何array_key_exists
    【解决方案3】:
    $url = "http://www.youtube.com/watch?v=TjTbNWhsG28#t=40m&foo=1&bar=2";
    $regex_pattern1 = "([#|\&]+t+\=+[0-9]+[m]+[0-9]+[s])"; // minutes and seconds
    $regex_pattern2 = "([#|\&]+t+\=+[0-9]+[m])"; // only minutes
    $regex_pattern3 = "([#|\&]+t+\=+[0-9]+[s])"; // only seconds
    $pattern_used = null;
    if(!preg_match_all($regex_pattern1, $url, $time)) // not found "#t=XmXs"
    {
        if(!preg_match_all($regex_pattern2, $url, $time)) // not found "#t=Xm"
        {
            if(!preg_match_all($regex_pattern3, $url, $time)) // not found "#t=Xs"
                die("Invalid URL");
            else $pattern_used = 3;
        }   
        else $pattern_used = 2;
    }
    else $pattern_used = 1;
    $time = substr($time[0][0], 3, strlen($time[0][0])); // deleting "#t="
    
    //echo $time; // prints "1m40s" or "40s" if only seconds are given
    
    // --------------
    $pattern_minutes = "([0-9]+[s])";
    $pattern_seconds = "([0-9]+[m])";
    if($pattern_used == 1) // we have both minutes and seconds defined
    {
        $minutes = preg_split($pattern_minutes, $time);
        $seconds = preg_split($pattern_seconds, $time);
    
        $array = array("minutes" => substr($minutes[0], 0, -1), 
                       "seconds" => substr($seconds[1], 0, -1));
    
        /* we have the following array now:
        array (size=2)
            'minutes' => string '1' (length=1)
            'seconds' => string '40' (length=2)*/
    }
    else
    {
        if($pattern_used == 2) $time2 = preg_split($pattern_minutes, $time);
        else $time2 = preg_split($pattern_seconds, $time); 
        $time2 = substr($time2[0], 0, -1);
        echo $time2; // prints "40"
    }
    

    【讨论】:

    • 你想念#t=10m&amp;t=3s
    • @burning_LEGION 我认为没有必要。
    • 谢谢!但是当只经过一分钟或一秒时,正则表达式似乎不起作用。正如我上面提到的,有时只有一个会在网址中:youtube.com/watch?v=TjTbNWhsG28#t=4s&foo=1&bar=2
    • 另一件事就是拆分这两个值,这样我就可以将它们转换为秒。将 1m40s 转换为像 array('m' => 1, 's'=> 40) 这样的数组的最佳方法是什么,同样条件是原始字符串中只能传递一个。
    • 谢谢!很近!我认为在几分钟但没有几秒钟的情况下它仍然失败,不是吗? youtube.com/watch?v=TjTbNWhsG28#t=1m&foo=1&bar=2
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 2020-11-21
    • 1970-01-01
    • 2014-11-20
    相关资源
    最近更新 更多