IT俱乐部 PHP JavaScript+PHP实现视频文件分片上传的示例代码

JavaScript+PHP实现视频文件分片上传的示例代码

摘要

视频文件分片上传,整体思路是利用JavaScript将文件切片,然后循环调用上传接口 upload.php 将切片上传到服务器。这样将由原来的一个大文件上传变为多个小文件同时上传,节省了上传时间,这就是文件分片上传的其中一个好处。

上代码

index.html

通过前端将文件对象切分成多个小块,然后依次将这些小块的文件对象上传到服务器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
     
        <title>视频文件分片上传</title>
            *{
                padding: 0;
                margin: 0;
            }
            .title {
                text-align: center;
                font-size: 25px;
                margin-top: 50px;
            }
            .video_upload {
                width: 500px;
                height: 60px;
                background: #eee;
                margin: 30px auto 0;
                border: 2px dashed #ccc;
                border-radius: 10px;
                position: relative;
                cursor: pointer;
                text-align: center;
                font-size: 25px;
                line-height: 60px;
                color: #666;
            }
            #fileInput {
                width: 100%;
                height: 100%;
                position: absolute;
                left: 0;
                top: 0;
                opacity: 0;
                cursor: pointer;
            }
            #uploadButton {
                width: 130px;
                height: 40px;
                border: none;
                outline: none;
                border-radius: 10px;
                font-size: 17px;
                margin: 10px auto;
            }
            #ret {
                text-align: center;
                font-size: 16px;
                margin-top: 20px;
            }
            #ret video {
                width: 450px;
            }
        <p class="title">javaScript+PHP实现视频文件分片上传</p>
        <div class="video_upload">
            <span class="text"> + </span>
             
</div>
        <button id="uploadButton">开始上传</button>
        <p id="ret"></p>
 
         
         
            // 定义全局变量
            let videoFile = null;
            let chunkSize = 1024 * 1024; // 1MB 分片大小
             
            // 当文件选择框的值改变时触发该函数
            function handleFileSelect(event) {
                const fileList = event.target.files;
                if (fileList.length > 0) {
                    videoFile = fileList[0];
                    console.log("选择了文件: ", videoFile.name);
                    document.querySelector('.video_upload .text').textContent = videoFile.name;
                    document.querySelector('#uploadButton').style.display = 'block';
                }
            }
             
            // 分片并上传文件
            async function uploadFile() {
                if (!videoFile) {
                    console.error("请选择一个视频文件");
                    return;
                }
             
                const fileSize = videoFile.size;
                let start = 0;
                let end = Math.min(chunkSize, fileSize);
                let chunkIndex = 0;
             
                // 获取文件名
                const fileName = videoFile.name;
             
                while (start < fileSize) {
                    const chunk = videoFile.slice(start, end); // 从文件中截取一个分片
             
                    // 使用FormData来构建multipart/form-data格式的请求体
                    const formData = new FormData();
                    formData.append('file', chunk);
                    formData.append('chunkIndex', chunkIndex);
                    formData.append('fileName', fileName); // 将文件名作为 formData 的一部分
             
                    try {
                        const response = await fetch('upload.php', {
                            method: 'POST',
                            body: formData
                        });
             
                        if (!response.ok) {
                            throw new Error('上传失败');
                        }
             
                        console.log('上传分片 ', chunkIndex, ' 成功');
                    } catch (error) {
                        console.error('上传分片 ', chunkIndex, ' 失败: ', error.message);
                        return;
                    }
             
                    start = end;
                    end = Math.min(start + chunkSize, fileSize);
                    chunkIndex++;
                }
             
                console.log('文件上传完成');
             
                // 上传完成后发送通知给服务器进行合并
                notifyServerForMerge(fileName);
            }
             
            // 发送通知给服务器进行合并
            async function notifyServerForMerge(fileName) {
                try {
                    const response = await fetch('merge_chunks.php', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        },
                        body: JSON.stringify({ fileName: fileName })
                    });
             
                    if (!response.ok) {
                        throw new Error('无法通知服务器进行合并');
                    }
                     
                    const res_data = await response.json();
             
                    console.log('已通知服务器进行合并');
                    document.querySelector('.video_upload .text').textContent = '分片合并完成!';
                    document.querySelector('#ret').innerHTML = '<video autoplay="" controls="" src="'+res_data.filePath+'" data-origwidth="0" data-origheight="0" style="width: 1264px;">';
                    document.querySelector('#uploadButton').style.display = 'none';
                } catch (error) {
                    console.error('通知服务器进行合并时发生错误: ', error.message);
                }
            }
             
            // 注册文件选择框的change事件
            document.getElementById('fileInput').addEventListener('change', handleFileSelect);
             
            // 注册上传按钮的click事件
            document.getElementById('uploadButton').addEventListener('click', uploadFile);
        </video>

upload.php

这个是用于接收前端传过来的每一段分片,然后上传到 uploads 文件夹,上传之后就是一段一段的小分片。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
'文件上传失败'
            ));
            exit();
        }
         
        // 设置存储目录和文件名
        $uploadDir = './uploads/';
        $filePath = $uploadDir . $fileName . '.' . $chunkIndex;
         
        // 将分片移动到指定的目录
        if (move_uploaded_file($_FILES['file']['tmp_name'], $filePath)) {
             
            echo json_encode(array(
                'success' => '分片上传成功'
            ));
        } else {
             
            http_response_code(500);
            echo json_encode(array(
                'error' => '分片上传失败'
            ));
        }
    } else {
         
        http_response_code(400);
        echo json_encode(array(
            'error' => '缺少文件、分片索引或文件名'
        ));
    }
     
?>

merge_chunks.php

这个是用来合并分片的,当前端完成上传分片的操作,前端会异步告诉服务器你已经完成所有分片的上传,接下来将每个分片名告诉合并程序完成所有分片的合并,合并之后就是一个完整的视频文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
0) {
             
            // 所有分片都已上传,开始合并
            $finalFile = fopen($finalFilePath, 'wb');
             
            // 逐个读取分片并写入最终文件
            for ($i = 0; $i  '文件合并成功',
                'filePath' => $finalFilePath
            ));
        } else {
             
            http_response_code(400);
            echo json_encode(array(
                'error' => '没有上传的分片'
            ));
        }
    } else {
         
        http_response_code(400);
        echo json_encode(array(
            'error' => '缺少文件名'
        ));
    }
?>

程序目录

请自行创建 uploads 目录。

以上就是JavaScript+PHP实现视频文件分片上传的示例代码的详细内容,更多关于JavaScript+PHP视频文件上传的资料请关注IT俱乐部其它相关文章!

本文收集自网络,不代表IT俱乐部立场,转载请注明出处。https://www.2it.club/code/php/10895.html
上一篇
下一篇
联系我们

联系我们

在线咨询: QQ交谈

邮箱: 1120393934@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部