视频分片上传

视频分片上传

# 基本原理
# 简单说就是将大文件分片上传,完成后再将全部分片进行合并。

/**
 * 资源上传控制器
 * ThinkPHP5 
 */
class Upload extends Common
{
    protected $chunk; // 当前上传文件的分片数
    protected $chunks; // 总分片数
    protected $savepath; // 保存地址
    protected $filename; // 文件名
    protected $filesize; // 文件大小

    /**
     * 构造函数
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * 视频分片上传
     */
    public function videoChunk()
    {
        // 这里须要注意的就是设置分配的最大内存不得小于容许的最大上传文件
        set_time_limit(0);
        ini_set('memory_limit', '1024M');

        // 获取文件相关信息,前端须要提交相关的文件信息
        $this->chunk = input('chunk');
        $this->chunks = input('chunks');
        $this->savepath = '/data/video/' . date('Ymd');
        $this->filename = input('name');
        $this->filesize = input('filesize');

        // 验证文件大小
        if ($this->filesize > (1 * 1024 * 1204 * 1024)) {
            response(401, '请不要上传超过 1G 的视频!');
        }

        // 接受上传分片
        $tmpname = $this->filename . '.tmp' . $this->chunk;
        $video = request()->file('video');
        // 判断是否有上传文件,存在则执行上传
        if ($video) {
            $info = $video->move($this->savepath, $tmpname);
            // 判断是否为最后一块,如果则合并
            if ($this->chunk == ($this->chunks - 1)) {
                $blob = '';
                for($i=0; $i< $this->chunks; $i++){
                    $blob .= file_get_contents($this->savepath. '/' . $this->filename . '.tmp' . $i);
                }
                file_put_contents($this->savepath . '/' . $this->filename, $blob);
                
                // 删除文件分片
                for ($i=0; $i< $this->chunks; $i++) {
                  @unlink($this->savepath . '/' . $this->filename . '.tmp' . $i);
                }

                response(200, '上传成功!', ['path' => $this->savepath . '/' . $this->filename]);
            }
        }
    }
}