如何制作过期/签名视频嵌入网址 [英] How to make Expiring/Signed video embed urls

查看:127
本文介绍了如何制作过期/签名视频嵌入网址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新手,学习网络开发等等。我只知道如何在网站上嵌入我的视频,并且可以通过任何新手轻松获得来源,他们也可以嵌入它。但是在很多网站上,视频src都是用重定向器链接编码的,例如: https://开头redirector.googlevideo.com/videoplayback?requiressl=yes&id=0c5d32687bb8e7fd&itag=18&source=webdrive&ttl=transient&app=explorer&ip=2604:a880:0:1010::dc7:d001&ipbits=32& ;到期= 1481329545&安培; sparams = requiressl%2Cid%2Citag%2Csource%2Cttl%2Cip%2Cipbits%2Cexpire&安培;签名= 8094D8DEF3C98784DC5561980B5725379B61A804.4C63CCB2 19699C4A2C02FB2606425E50243F8D36& key = ck2& mm = 31& mn = sn-ab5l6ne6& ms = au& mt = 1481314943& mv = m& nh = IgpwcjA0LmxnYTA3KgkxMjcuMC4wLjE& pl = 48

I'm new and learning web development and all. I only know how to embed my videos in the website and the source can be easily obtained by any noobs and they can embed it too. but in many website the video src is encoded with a redirector link, for example: https://redirector.googlevideo.com/videoplayback?requiressl=yes&id=0c5d32687bb8e7fd&itag=18&source=webdrive&ttl=transient&app=explorer&ip=2604:a880:0:1010::dc7:d001&ipbits=32&expire=1481329545&sparams=requiressl%2Cid%2Citag%2Csource%2Cttl%2Cip%2Cipbits%2Cexpire&signature=8094D8DEF3C98784DC5561980B5725379B61A804.4C63CCB219699C4A2C02FB2606425E50243F8D36&key=ck2&mm=31&mn=sn-ab5l6ne6&ms=au&mt=1481314943&mv=m&nh=IgpwcjA0LmxnYTA3KgkxMjcuMC4wLjE&pl=48

一段时间后过期,在这种情况下,一天。我已经知道这是一个签名的网址。

It expires after some time, in this case, a day. I've learnt that this is a signed url.

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

So, i would like to know how to create a signed url like this. Please dont give any plugin names coz i'm not a paid user or anything i'm using blogger only. i just wanna learn how to code it in javascript.

简而言之,我想让我们说,我的嵌入式YouTube视频的来源是一个签名的网址,后来过期了一个小时,当网站刷新时,来源应该不断变化。

In short, I want to make lets say, source of my embeded youtube video to be a signed url which expires after an hour and the source should keep changing when the site is refreshed.

推荐答案

编辑:做完之后这个,我注意到你使用的是YouTube视频嵌入,而不是实际的视频文件。但是没关系,我会把它放在这里...

After doing this, I noticed you were using YouTube video embeds, not actual video files. But nevermind, I'll just leave this here...

既然你没有在任何地方提到NodeJS,我就是猜测你期望在浏览器中用JS做这件事。但是为了在浏览器中实现这一点,您需要将真实的视频URL发送到客户端,并向公众公开您的URL签名功能。这违背了签署网址的目的。

Since you did not mention NodeJS anywhere, I'm guessing you're expecting to do this in JS in the browser. But for that to happen in the browser, you would need the have the real video URL sent to the client, and expose to the public your URL signing functions. Which defeats the purpose of having signed URLs.

我尝试使用PHP,它并不是很复杂。以下是流程:

I gave it a try using PHP, and it's not very complicated. Here is the process:

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

When a user requests your page, you create a temporary URL for him. This URL contains a signature, which contains the filepath to the video and an expiration date. It leads to a page which will translate the signature, and serve the file if everything is correct.

我看到你不想使用库,但我用过自制的图书馆,这将有助于保持井井有条。这是我使用的文件结构:

I see you don't want to use libraries, but I used "home made" libraries, which will help keep things well organized. Here is the file structure I used:

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

libraries / VideoSignature.php

请注意,您需要更改顶部的设置以满足您的需求

Note that you need to change the settings at the top to suit your needs

<?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;
    }
}

libraries / VideoStream.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();
    }
}

index.php

<?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>

getVideo.php

<?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.";
}

这篇关于如何制作过期/签名视频嵌入网址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆