Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使过期/签名视频嵌入URL_Javascript_Video_Pre Signed Url - Fatal编程技术网

Javascript 如何使过期/签名视频嵌入URL

Javascript 如何使过期/签名视频嵌入URL,javascript,video,pre-signed-url,Javascript,Video,Pre Signed Url,我是新来的,正在学习网络开发等。我只知道如何将我的视频嵌入到网站中,任何noob都可以很容易地获取视频源,他们也可以嵌入视频。但在许多网站中,视频src使用重定向器链接进行编码,例如: 它在一段时间后到期,在本例中为一天。我知道这是一个签名的url 所以,我想知道如何创建这样的签名url。请不要给出任何插件名称,因为我不是付费用户或任何我只使用博客的东西。我只是想学习如何用javascript编写代码 简言之,我想让我嵌入的youtube视频的源成为一个签名url,一小时后过期,当站点刷新时,源

我是新来的,正在学习网络开发等。我只知道如何将我的视频嵌入到网站中,任何noob都可以很容易地获取视频源,他们也可以嵌入视频。但在许多网站中,视频src使用重定向器链接进行编码,例如:

它在一段时间后到期,在本例中为一天。我知道这是一个签名的url

所以,我想知道如何创建这样的签名url。请不要给出任何插件名称,因为我不是付费用户或任何我只使用博客的东西。我只是想学习如何用javascript编写代码


简言之,我想让我嵌入的youtube视频的源成为一个签名url,一小时后过期,当站点刷新时,源应该不断更改。

编辑:完成此操作后,我注意到您使用的是youtube视频嵌入,而不是实际的视频文件。但是没关系,我会把这个留在这里


由于您没有在任何地方提到NodeJS,我猜您希望在浏览器的JS中这样做。但要在浏览器中实现这一点,您需要将真实的视频URL发送到客户端,并向公众公开您的URL签名功能。这违背了签署URL的目的

我用PHP尝试了一下,它并不复杂。过程如下:

当用户请求您的页面时,您为他创建一个临时URL。此URL包含一个签名,其中包含视频的文件路径和过期日期。它将导致一个页面,该页面将翻译签名,并在一切都正确的情况下提供文件

我知道你不想使用图书馆,但我使用了“自制”的图书馆,这将有助于使事情井然有序。以下是我使用的文件结构:

/
├── libraries/
│   ├── VideoStream.php
│   └── VideoSignature.php
├── index.php
├── video.mp4
└── getVideo.php
库/VideoSignature.php

<?php

/*
 * This class was found here:
 * http://stackoverflow.com/a/39897793/1913729
 *
 * It allows you to stream video without giving the real file URL
 */

class VideoStream
{
    private $path = "";
    private $stream = "";
    private $buffer = 102400;
    private $start  = -1;
    private $end    = -1;
    private $size   = 0;

    function __construct($filePath) 
    {
        $this->path = $filePath;
    }

    /**
     * Open stream
     */
    private function open()
    {
        if (!($this->stream = fopen($this->path, 'rb'))) {
            die('Could not open stream for reading');
        }

    }

    /**
     * Set proper header to serve the video content
     */
    private function setHeader()
    {
        ob_get_clean();
        header("Content-Type: video/mp4");
        header("Cache-Control: max-age=2592000, public");
        header("Expires: ".gmdate('D, d M Y H:i:s', time()+2592000) . ' GMT');
        header("Last-Modified: ".gmdate('D, d M Y H:i:s', @filemtime($this->path)) . ' GMT' );
        $this->start = 0;
        $this->size  = filesize($this->path);
        $this->end   = $this->size - 1;
        header("Accept-Ranges: 0-".$this->end);

        if (isset($_SERVER['HTTP_RANGE'])) {

            $c_start = $this->start;
            $c_end = $this->end;

            list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
            if (strpos($range, ',') !== false) {
                header('HTTP/1.1 416 Requested Range Not Satisfiable');
                header("Content-Range: bytes $this->start-$this->end/$this->size");
                exit;
            }
            if ($range == '-') {
                $c_start = $this->size - substr($range, 1);
            }else{
                $range = explode('-', $range);
                $c_start = $range[0];

                $c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $c_end;
            }
            $c_end = ($c_end > $this->end) ? $this->end : $c_end;
            if ($c_start > $c_end || $c_start > $this->size - 1 || $c_end >= $this->size) {
                header('HTTP/1.1 416 Requested Range Not Satisfiable');
                header("Content-Range: bytes $this->start-$this->end/$this->size");
                exit;
            }
            $this->start = $c_start;
            $this->end = $c_end;
            $length = $this->end - $this->start + 1;
            fseek($this->stream, $this->start);
            header('HTTP/1.1 206 Partial Content');
            header("Content-Length: ".$length);
            header("Content-Range: bytes $this->start-$this->end/".$this->size);
        }
        else
        {
            header("Content-Length: ".$this->size);
        }  

    }

    /**
     * close curretly opened stream
     */
    private function end()
    {
        fclose($this->stream);
        exit;
    }

    /**
     * perform the streaming of calculated range
     */
    private function stream()
    {
        $i = $this->start;
        set_time_limit(0);
        while(!feof($this->stream) && $i <= $this->end) {
            $bytesToRead = $this->buffer;
            if(($i+$bytesToRead) > $this->end) {
                $bytesToRead = $this->end - $i + 1;
            }
            $data = fread($this->stream, $bytesToRead);
            echo $data;
            flush();
            $i += $bytesToRead;
        }
    }

    /**
     * Start streaming video content
     */
    function start()
    {
        $this->open();
        $this->setHeader();
        $this->stream();
        $this->end();
    }
}
<?php

// Load the signature helper functions
include "libraries/VideoSignature.php";
$vs = new VideoSignature();

?><!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Check out my video!</title>
</head>
<body>
    <!-- /!\ Here, you need to insert a path to your video,
         relative to the getVideo.php file, not an actual URL! -->
    <video src="<?=$vs->getSignedURL("server/path/to/video.mp4");?>"></video>
</body>
</html>
<?php

// Load the signature helper functions
include "libraries/VideoSignature.php";
$vs = new VideoSignature();
// Load the video streaming functions
include "libraries/VideoStream.php";


if(isset($_REQUEST['s']) && $filepath = $vs->getFilepath($_REQUEST['s'])){
    $stream = new VideoStream($filepath);
    $stream->start();
} else {
    header("HTTP/1.0 403 Forbidden");
    echo "This URL has expired.";
}
请注意,您需要更改顶部的设置以满足您的需要

<?php

/*
 * This class allows you to:
 * - Encrypt filepaths and expiration dates into signatures
 * - Decrypt signatures into filepaths and expiration dates
 *
 *
 * Note: String encryption functions were found here:
 * http://stackoverflow.com/a/1289114/1913729
 */

class VideoSignature
{
    // Time before a URL expires, in seconds
    private $expires = 10;
    // Key used to sign your URLs
    private $encryption_key = 'soMeStr0ngP455W0rD!!';
    // Public URL used to serve the content
    private $proxy_url = '/getVideo.php';

    // Encrypts a string
    private function encryptStr($str){
        $iv = mcrypt_create_iv(
            mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC),
            MCRYPT_DEV_URANDOM
        );

        $encrypted = base64_encode(
            $iv .
            mcrypt_encrypt(
                MCRYPT_RIJNDAEL_128,
                hash('sha256', $this->encryption_key, true),
                $str,
                MCRYPT_MODE_CBC,
                $iv
            )
        );

        return $encrypted;
    }

    // Decrypts a String
    private function decryptStr($str){
        $data = base64_decode($str);
        $iv = substr($data, 0, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));

        $decrypted = rtrim(
            mcrypt_decrypt(
                MCRYPT_RIJNDAEL_128,
                hash('sha256', $this->encryption_key, true),
                substr($data, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)),
                MCRYPT_MODE_CBC,
                $iv
            ),
            "\0"
        );

        return $decrypted;
    }

    // Returns a temporary URL
    public function getSignedURL($filepath){
        $data = json_encode(
                array(
                    "filepath" => $filepath,
                    "expires" => time() + $this->expires
                )
            );

        $signature = $this->encryptStr($data);

        return $this->proxy_url . "?s=" . urlencode($signature);
    }

    // Returns a filepath from a signature if it did not expire
    public function getFilepath($signature){
        $data = json_decode( $this->decryptStr($signature), true);

        if($data !== null && $data['expires'] > time() && file_exists($data['filepath'])){
            return $data['filepath'];
        }

        return false;
    }
}

看看我的视频!

有一点是肯定的,如果你要创建签名的URL,不要在JS中创建,因为这是在浏览器中发生的,需要将永久URL发送到客户端(通过查看代码很容易获得)。你应该在服务器端完成。你在使用PHP吗?这段视频声称要解释这个概念,并展示作者是如何实现的:。注意:JS可以在服务器端运行。不仅是youtube视频,还可以嵌入yourupload、mp4upload等视频。对不起,我不熟悉NodeJS,但是哪种方法最简单?我愿意学习。@Andruraj你不需要使用NodeJS。PHP或任何其他服务器端语言都可以。只是如果你想在JS中完成,你需要在服务器端(使用NodeJS)完成,而不是在浏览器中。话虽如此,不幸的是,我看不到任何方法可以通过第三方网站嵌入代码来实现。您的iframe的URL最终将成为站点的URL,并且在播放器中通常有一个指向托管网站的链接:(+1非常精彩的描述..你的代码非常精彩,非常详细,但我更喜欢nodejs我不是php的家伙,但我得到了这个想法如果你不是一个非常好的有意用户,那么在你观看视频时获取视频源是否相对容易?@TrOnNe是的,这种方法不是非常安全。你确实需要一个活动的、签名的URL,但是如果您这样做,在链接仍然有效的情况下下载视频将非常容易。您只需打开浏览器开发工具中的“网络”选项卡,右键单击为视频服务的请求,然后选择“另存为…”