LoginSignup
1
1

More than 5 years have passed since last update.

Azure Blob(動画ファイル)を分割アップロードしてみた

Last updated at Posted at 2018-08-17

Azure Blobを分割してアップロードしてみた

Azureにアップロードする際にどうも一括アップロードの容量制限があるのでそれを対応してみたお話
ついでにPHPの容量制限も上げたくなかった><

ざっくり流れ

フロント => PHP => Azure

  • フロントからファイルアップロードして分割で(jQuery-File-Uploadを利用
  • PHPで分割されたファイルを受け取ってtmpフォルダに突っ込む
  • フロントからデータの転送がすべて終わったら、PHPからAzureに送るやつを呼ぶ
  • PHPからAzureに分割してデータを送って最後に1まとめにして完了!(azure-storage-php

フロント

※めちゃくちゃパクりましたm(_ _)m
jQuery-File-Upload サンプル
https://qiita.com/shiccocsan/items/074e03c5f41f986afc29

maxChunkSize と unique_keyを付けてるところが重要
unique_keyはPHPで作ってAPIでもらう流れ作ったほうが安全そう

<script src="file_upload/js/vendor/jquery.ui.widget.js"></script>
<script src="file_upload/js/jquery.iframe-transport.js"></script>
<script src="file_upload/js/jquery.fileupload.js"></script>
<link rel="stylesheet" href="file_upload/css/jquery.fileupload.css" />

<span class="btn btn-success fileinput-button">
        <i class="glyphicon glyphicon-plus"></i>
        <span>Select files...</span>
        <input id="fileupload" type="file" name="files[]" multiple>
    </span>
<br>
<br>
<!-- The global progress bar -->
<div id="progress" class="progress">
    <div class="progress-bar progress-bar-success"></div>
</div>

<script>
        $(function () {
            'use strict';

            let url = "/upload"; // 要url変更
            let commit_url = "/commit"; // 要url変更
            $('#fileupload').fileupload({
                url: url,
                dataType: 'json',
                maxChunkSize: 5242880, // ここを指定して分割アップロードさせる5M毎
                add: function (e, data) {
                    let unique_key = Math.floor(Math.random() * 1000);
                    data.unique_key = unique_key;
                    data.submit();
                },
                done: function (e, data) {
                    $.each(data.result.files, function (index, file) {
                        $('<p/>').text(file.name).appendTo('#files');
                    });
                    // 全部送信し終わったら、Azureにアップロードする処理を呼ぶ
                    $.ajax(commit_url, {
                        type: "POST",
                        data: {'file_name': data.files[0].unique_key},
                    })
                },
                progressall: function (e, data) {
                    var progress = parseInt(data.loaded / data.total * 100, 10);
                    $('#progress .progress-bar').css(
                            'width',
                            progress + '%'
                    );
                }
            }).prop('disabled', !$.support.fileInput)
                    .parent().addClass($.support.fileInput ? undefined : 'disabled');
        });
</script>

バックエンド

Phalconベースなのでメソッド適当に置き換えてくだし><

PHP Azureライブラリ
https://github.com/Azure/azure-storage-php


    /**
    * 分割アップロードの処理
    **/
    public function uploadAction()
    {
        $request = new Request();
        if ($request->hasFiles() == true) {
            foreach ($this->request->getUploadedFiles() as $file) {
                // tmpフォルダに連番を付けて置く
                $tmpDir = "/tmp/" . $request->get('unique_key');
                $count = $this->getFileCount($tmpDir);
                $file->moveTo($tmpDir . '/' . $count);
            }
        }
    }

    /**
    * 分割アップロードが終わった後にAzureに送る処理
    **/
    public function commitAction()
    {
        $request = new Request();
        $tmpDir = '/tmp/' . $request->get('unique_key');
        $blobName = 'なんか名前';

        $connectionString = 'DefaultEndpointsProtocol=https;AccountName=hogehoge;AccountKey=hogehgoeghoege==;';
        $containerName = "hogehoge";

        $blobClient = BlobRestProxy::createBlobService($connectionString);

        $blockId = 1;
        $blockList = new BlockList();
        $count = $this->getFileCount($tmpDir);
        foreach (range(0, $count - 1) as $i)
        {
            $file_path = $tmpDir . '/' . $i;
            $content = file_get_contents($file_path);

            //upload the block
            $blobClient->createBlobBlock($containerName, $blobName, md5($blockId),$content);
            $blockList->addLatestEntry(md5($blockId)); //you need to maintain a list of all the blockIds that are a part of this blob
            $blockId++;
        }

        $options = new CommitBlobBlocksOptions();
        // $options->setContentType('video/mp4'); // 必要であれば適宜
        $blobClient->commitBlobBlocks(
            $containerName,
            $blobName,
            $blockList->getEntries(),
            $options
        ); //Merge all the blockIds to form the blob.

        return $blobClient->getBlobUrl($containerName, $blobName);
    }

こんなかんじですると
- PHPのデータ容量をあげずに
- Azureのデータ制限を回避しつつ
- アップロードができる!

適当にソース書き換えてアップしたので適宜書き換えてください!

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1