设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间12 现在时间12 缓存数据 最初知道八爷还是各种v曲,现在变化真的好大。八爷被越来越多的人喜欢,隐隐有种珍藏心底的东西被发现的难受,新歌这么快就破千了[流泪]这家伙真是太美好了❤️❤️

最初知道八爷还是各种v曲,现在变化真的好大。八爷被越来越多的人喜欢,隐隐有种珍藏心底的东西被发现的难受,新歌这么快就破千了[流泪]这家伙真是太美好了❤️❤️ -- Lemon

查看: 1149|回复: 4

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

[复制链接]

  离线 

TA的专栏

  • 打卡等级:热心大叔
  • 打卡总天数:205
  • 打卡月天数:0
  • 打卡总奖励:3233
  • 最近打卡:2023-08-27 07:19:29
等级头衔

等級:晓枫资讯-上等兵

在线时间
0 小时

积分成就
威望
0
贡献
387
主题
351
精华
0
金钱
4350
积分
758
注册时间
2022-12-24
最后登录
2025-5-31

发表于 2024-4-11 22:06:31 | 显示全部楼层 |阅读模式
目录


  • 摘要
  • 上代码
  • 程序目录

摘要

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


上代码

index.html
通过前端将文件对象切分成多个小块,然后依次将这些小块的文件对象上传到服务器。
  1. <!DOCTYPE html>
  2. <html lang="en">
  3.         <head>
  4.                 <meta charset="UTF-8">
  5.                 <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.                 <title>视频文件分片上传</title>
  7.                 <style>
  8.                     *{
  9.                         padding: 0;
  10.                         margin: 0;
  11.                     }
  12.                     .title {
  13.                         text-align: center;
  14.                         font-size: 25px;
  15.                         margin-top: 50px;
  16.                     }
  17.                     .video_upload {
  18.                         width: 500px;
  19.                         height: 60px;
  20.                         background: #eee;
  21.                         margin: 30px auto 0;
  22.                         border: 2px dashed #ccc;
  23.                         border-radius: 10px;
  24.                         position: relative;
  25.                         cursor: pointer;
  26.                         text-align: center;
  27.                         font-size: 25px;
  28.                         line-height: 60px;
  29.                         color: #666;
  30.                     }
  31.                     #fileInput {
  32.                         width: 100%;
  33.                         height: 100%;
  34.                         position: absolute;
  35.                         left: 0;
  36.                         top: 0;
  37.                         opacity: 0;
  38.                         cursor: pointer;
  39.                     }
  40.                     #uploadButton {
  41.                         width: 130px;
  42.                         height: 40px;
  43.                         border: none;
  44.                         outline: none;
  45.                         border-radius: 10px;
  46.                         font-size: 17px;
  47.                         margin: 10px auto;
  48.                     }
  49.                     #ret {
  50.                         text-align: center;
  51.                         font-size: 16px;
  52.                         margin-top: 20px;
  53.                     }
  54.                     #ret video {
  55.                         width: 450px;
  56.                     }
  57.                 </style>
  58.         </head>
  59.         <body>
  60.             
  61.         <p class="title">javaScript+PHP实现视频文件分片上传</p>
  62.         <div class="video_upload">
  63.             <span class="text"> + </span>
  64.             <input type="file" id="fileInput" accept="video/*">
  65.         </div>
  66.                 <button id="uploadButton" style="display:none;">开始上传</button>
  67.                 <p id="ret"></p>

  68.                 <script>
  69.                
  70.                         // 定义全局变量
  71.                         let videoFile = null;
  72.                         let chunkSize = 1024 * 1024; // 1MB 分片大小
  73.                        
  74.                         // 当文件选择框的值改变时触发该函数
  75.                         function handleFileSelect(event) {
  76.                             const fileList = event.target.files;
  77.                             if (fileList.length > 0) {
  78.                                 videoFile = fileList[0];
  79.                                 console.log("选择了文件: ", videoFile.name);
  80.                                 document.querySelector('.video_upload .text').textContent = videoFile.name;
  81.                                 document.querySelector('#uploadButton').style.display = 'block';
  82.                             }
  83.                         }
  84.                        
  85.                         // 分片并上传文件
  86.                         async function uploadFile() {
  87.                             if (!videoFile) {
  88.                                 console.error("请选择一个视频文件");
  89.                                 return;
  90.                             }
  91.                        
  92.                             const fileSize = videoFile.size;
  93.                             let start = 0;
  94.                             let end = Math.min(chunkSize, fileSize);
  95.                             let chunkIndex = 0;
  96.                        
  97.                             // 获取文件名
  98.                             const fileName = videoFile.name;
  99.                        
  100.                             while (start < fileSize) {
  101.                                 const chunk = videoFile.slice(start, end); // 从文件中截取一个分片
  102.                        
  103.                                 // 使用FormData来构建multipart/form-data格式的请求体
  104.                                 const formData = new FormData();
  105.                                 formData.append('file', chunk);
  106.                                 formData.append('chunkIndex', chunkIndex);
  107.                                 formData.append('fileName', fileName); // 将文件名作为 formData 的一部分
  108.                        
  109.                                 try {
  110.                                     const response = await fetch('upload.php', {
  111.                                         method: 'POST',
  112.                                         body: formData
  113.                                     });
  114.                        
  115.                                     if (!response.ok) {
  116.                                         throw new Error('上传失败');
  117.                                     }
  118.                        
  119.                                     console.log('上传分片 ', chunkIndex, ' 成功');
  120.                                 } catch (error) {
  121.                                     console.error('上传分片 ', chunkIndex, ' 失败: ', error.message);
  122.                                     return;
  123.                                 }
  124.                        
  125.                                 start = end;
  126.                                 end = Math.min(start + chunkSize, fileSize);
  127.                                 chunkIndex++;
  128.                             }
  129.                        
  130.                             console.log('文件上传完成');
  131.                        
  132.                             // 上传完成后发送通知给服务器进行合并
  133.                             notifyServerForMerge(fileName);
  134.                         }
  135.                        
  136.                         // 发送通知给服务器进行合并
  137.                         async function notifyServerForMerge(fileName) {
  138.                             try {
  139.                                 const response = await fetch('merge_chunks.php', {
  140.                                     method: 'POST',
  141.                                     headers: {
  142.                                         'Content-Type': 'application/json'
  143.                                     },
  144.                                     body: JSON.stringify({ fileName: fileName })
  145.                                 });
  146.                        
  147.                                 if (!response.ok) {
  148.                                     throw new Error('无法通知服务器进行合并');
  149.                                 }
  150.                                 
  151.                                 const res_data = await response.json();
  152.                        
  153.                                 console.log('已通知服务器进行合并');
  154.                                 document.querySelector('.video_upload .text').textContent = '分片合并完成!';
  155.                                 document.querySelector('#ret').innerHTML = '<video autoplay controls src="'+res_data.filePath+'"></video>';
  156.                                 document.querySelector('#uploadButton').style.display = 'none';
  157.                             } catch (error) {
  158.                                 console.error('通知服务器进行合并时发生错误: ', error.message);
  159.                             }
  160.                         }
  161.                        
  162.                         // 注册文件选择框的change事件
  163.                         document.getElementById('fileInput').addEventListener('change', handleFileSelect);
  164.                        
  165.                         // 注册上传按钮的click事件
  166.                         document.getElementById('uploadButton').addEventListener('click', uploadFile);
  167.                 </script>

  168.         </body>
  169. </html>
复制代码
upload.php
这个是用于接收前端传过来的每一段分片,然后上传到
  1. uploads
复制代码
文件夹,上传之后就是一段一段的小分片。
  1. <?php

  2.     // 设置允许跨域访问
  3.     header("Access-Control-Allow-Origin: *");
  4.     header("Access-Control-Allow-Methods: POST");
  5.    
  6.     // 检查是否接收到文件和分片索引
  7.     if (isset($_FILES['file']['error']) && isset($_POST['chunkIndex']) && isset($_POST['fileName'])) {
  8.         
  9.         $error = $_FILES['file']['error'];
  10.         $chunkIndex = $_POST['chunkIndex'];
  11.         $fileName = $_POST['fileName']; // 获取文件名
  12.         
  13.         // 检查是否有错误
  14.         if ($error !== UPLOAD_ERR_OK) {
  15.             http_response_code(500);
  16.             echo json_encode(array(
  17.                 'error' => '文件上传失败'
  18.             ));
  19.             exit();
  20.         }
  21.         
  22.         // 设置存储目录和文件名
  23.         $uploadDir = './uploads/';
  24.         $filePath = $uploadDir . $fileName . '.' . $chunkIndex;
  25.         
  26.         // 将分片移动到指定的目录
  27.         if (move_uploaded_file($_FILES['file']['tmp_name'], $filePath)) {
  28.             
  29.             echo json_encode(array(
  30.                 'success' => '分片上传成功'
  31.             ));
  32.         } else {
  33.             
  34.             http_response_code(500);
  35.             echo json_encode(array(
  36.                 'error' => '分片上传失败'
  37.             ));
  38.         }
  39.     } else {
  40.         
  41.         http_response_code(400);
  42.         echo json_encode(array(
  43.             'error' => '缺少文件、分片索引或文件名'
  44.         ));
  45.     }
  46.    
  47. ?>
复制代码
merge_chunks.php
这个是用来合并分片的,当前端完成上传分片的操作,前端会异步告诉服务器你已经完成所有分片的上传,接下来将每个分片名告诉合并程序完成所有分片的合并,合并之后就是一个完整的视频文件。
  1. <?php

  2.     // 设置允许跨域访问
  3.     header("Access-Control-Allow-Origin: *");
  4.     header("Access-Control-Allow-Methods: POST");
  5.     header("Content-Type: application/json");
  6.    
  7.     // 获取请求体中的文件名
  8.     $data = json_decode(file_get_contents("php://input") , true);
  9.     $fileName = isset($data['fileName']) ? $data['fileName'] : null;
  10.     if ($fileName) {
  11.         
  12.         $uploadDir = './uploads/';
  13.         $finalFilePath = $uploadDir . $fileName;
  14.         $totalChunks = count(glob($uploadDir . $fileName . '.*'));
  15.         
  16.         // 检查是否所有分片都已上传
  17.         if ($totalChunks > 0) {
  18.             
  19.             // 所有分片都已上传,开始合并
  20.             $finalFile = fopen($finalFilePath, 'wb');
  21.             
  22.             // 逐个读取分片并写入最终文件
  23.             for ($i = 0; $i < $totalChunks; $i++) {
  24.                 $chunkFilePath = $uploadDir . $fileName . '.' . $i;
  25.                 $chunkFile = fopen($chunkFilePath, 'rb');
  26.                 stream_copy_to_stream($chunkFile, $finalFile);
  27.                 fclose($chunkFile);
  28.                 unlink($chunkFilePath); // 删除已合并的分片
  29.                
  30.             }
  31.             
  32.             fclose($finalFile);
  33.             http_response_code(200);
  34.             echo json_encode(array(
  35.                 'success' => '文件合并成功',
  36.                 'filePath' => $finalFilePath
  37.             ));
  38.         } else {
  39.             
  40.             http_response_code(400);
  41.             echo json_encode(array(
  42.                 'error' => '没有上传的分片'
  43.             ));
  44.         }
  45.     } else {
  46.         
  47.         http_response_code(400);
  48.         echo json_encode(array(
  49.             'error' => '缺少文件名'
  50.         ));
  51.     }
  52. ?>
复制代码
程序目录

请自行创建
  1. uploads
复制代码
目录。
2.webp

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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
14
积分
8
注册时间
2022-12-24
最后登录
2022-12-24

发表于 2024-10-25 12:10:49 | 显示全部楼层
顶顶更健康!!!
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
16
积分
12
注册时间
2022-12-24
最后登录
2022-12-24

发表于 2025-2-15 20:09:43 | 显示全部楼层
感谢楼主,顶。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
22
积分
24
注册时间
2022-12-30
最后登录
2022-12-30

发表于 2025-3-21 21:00:20 | 显示全部楼层
感谢楼主分享。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
21
积分
22
注册时间
2022-12-25
最后登录
2022-12-25

发表于 2025-3-26 00:19:03 | 显示全部楼层
路过,支持一下
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1楼
2楼
3楼
4楼
5楼

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表