2014-02-18 96 views
1

我想使用PHP上传视频文件,并通过进度条显示上传进度。但是这样比较困难,就像我认为的那样,我试图把拼凑起来的拼图放在一起,但不幸的是我没有找到所需的php,ajax和html代码一起工作的代码片段,所以我试图将不同的拼凑在一起。使用Javascript和PHP的视频文件上传进度条

我的代码功能几乎完全。唯一的问题是,目前的文件上传过程中,我已经得到了百分之,是由我的JavaScript加载后,过程已经结束,而不是从一开始。

这是我的PHP代码:

function file_get_size($file) { 
    //open file 
    $fh = fopen($file, "r"); 
    //declare some variables 
    $size = "0"; 
    $char = ""; 
    //set file pointer to 0; I'm a little bit paranoid, you can remove this 
    fseek($fh, 0, SEEK_SET); 
    //set multiplicator to zero 
    $count = 0; 
    while (true) { 
     //jump 1 MB forward in file 
     fseek($fh, 1048576, SEEK_CUR); 
     //check if we actually left the file 
     if (($char = fgetc($fh)) !== false) { 
      //if not, go on 
      $count ++; 
     } else { 
      //else jump back where we were before leaving and exit loop 
      fseek($fh, -1048576, SEEK_CUR); 
      break; 
     } 
    } 
    //we could make $count jumps, so the file is at least $count * 1.000001 MB large 
    //1048577 because we jump 1 MB and fgetc goes 1 B forward too 
    $size = bcmul("1048577", $count); 
    //now count the last few bytes; they're always less than 1048576 so it's quite fast 
    $fine = 0; 
    while(false !== ($char = fgetc($fh))) { 
     $fine ++; 
    } 
    //and add them 
    $size = bcadd($size, $fine); 
    fclose($fh); 
    return $size; 
} 
$filesize = file_get_size('remote-file'); 

$remote = fopen('remote-file', 'r'); 
$local = fopen('local-file', 'w'); 

$read_bytes = 0; 
while(!feof($remote)) { 
    $buffer = fread($remote, 2048); 
    fwrite($local, $buffer); 

    $read_bytes += 2048; 

    //Use $filesize as calculated earlier to get the progress percentage 
    $progress = min(100, 100 * $read_bytes/$filesize); 
    fwrite(fopen('files/upload/progress.txt', 'w'), $progress); 

    //you'll need some way to send $progress to the browser. 
    //maybe save it to a file and then let an Ajax call check it? 
} 
fclose($remote); 
fclose($local); 

这是我的JavaScript代码:

function main() 
{ 
    var pathOfFileToRead = "files/upload/progress.txt"; 

    var contentsOfFileAsString = FileHelper.readStringFromFileAtPath 
    (
     pathOfFileToRead 
    ); 

    document.body.innerHTML = contentsOfFileAsString; 
} 

function FileHelper() 
{} 
{ 
    FileHelper.readStringFromFileAtPath = function(pathOfFileToReadFrom) 
    { 
     var request = new XMLHttpRequest(); 
     request.open("GET", pathOfFileToReadFrom, false); 
     request.send(null); 
     var returnValue = request.responseText; 

     return returnValue; 
    } 
} 

main(); 

function progressBarSim(al) { 
    var bar = document.getElementById('bar-fill'); 
    var status = document.getElementById('status'); 
    status.innerHTML = al+"%"; 
    bar.value = al; 
    al++; 
var sim = setTimeout("progressBarSim("+al+")",1000); 
if(al == 100){ 
status.innerHTML = "100%"; 
bar.value = 100; 
clearTimeout(sim); 
var finalMessage = document.getElementById('finalMessage'); 
finalMessage.innerHTML = "Process is complete"; 
} 
} 
var amountLoaded = 0; 
progressBarSim(amountLoaded); 

进度条就目前的工作在一个定时器,因为main()函数犯规阅读的内容“progress.txt”从一开始,但只在最后。所以我想有一些帮助将progressBarSim和main()结合起来。

* 编辑:*我发现了一段代码:http://www.it-gecko.de/html5-file-upload-fortschrittanzeige-progressbar.html,我现在正在使用它。

+0

你真的明白ajax是什么吗? 它看起来像你没有,Ajax被用来调用一个PHP脚本,并从它获得响应,而无需在浏览器中重新加载页面。 所以你在这里使用的不是Ajax,它不能工作,因为PHP将首先完全执行。所以当浏览器使用主函数时,文件表示完成是合乎逻辑的。 – MisterJ

+0

你也用ffmpeg? – cocco

+0

我没有使用ffmpeg,也没有太多有关javascript和ajax的经验,这就是为什么我犯了这个错误。 – hardking

回答

0

这里是现代的浏览器的AJAX功能:

//url,callback,type,FormData,uploadFunc,downloadFunc 
function ajax(a,b,e,d,f,g,c){ 
c=new XMLHttpRequest; 
!f||(c.upload.onprogress=f); 
!g||(c.onprogress=g); 
c.onload=b; 
c.open(e||'get',a); 
c.send(d||null) 
} 

更多关于此功能https://stackoverflow.com/a/18309057/2450730

下面是HTML

<form><input type="file" name="file"><input type="submit" value="GO"></form> 
<canvas width="64" height="64"></canvas> 
<canvas width="64" height="64"></canvas> 
<pre></pre> 

您可以添加表单内更多领域而且你不需要改变javascript函数中的任何东西。 它总是发送整个表格

这是使这一AJAX功能工作

var canvas,pre; 
window.onload=function(){ 
canvas=document.getElementsByTagName('canvas'); 
pre=document.getElementsByTagName('pre')[0]; 
document.forms[0].onsubmit=function(e){ 
    e.preventDefault(); 
    ajax('upload.php',rdy,'post',new FormData(this),progressup,progressdown) 
} 
} 
function progressup(e){ 
animate(e.loaded/e.total,canvas[0],'rgba(127,227,127,0.3)') 
} 
function progressdown(e){ 
animate(e.loaded/e.total,canvas[1],'rgba(227,127,127,0.3)') 
} 
function rdy(e){ 
pre.textContent=this.response; 
} 

代码这是移动的圆形画布进度条

function animate(p,C,K){ 
var c=C.getContext("2d"), 
x=C.width/2, 
r=x-(x/4), 
s=(-90/180)*Math.PI, 
p=p||0, 
e=(((p*360|0)-90)/180)*Math.PI; 
c.clearRect(0,0,C.width,C.height); 
c.fillStyle=K; 
c.textAlign='center'; 
c.font='bold '+(x/2)+'px Arial'; 
c.fillText(p*100|0,x,x+(x/5)); 
c.beginPath(); 
c.arc(x,x,r,s,e); 
c.lineWidth=x/2; 
c.strokeStyle=K; 
c.stroke(); 
} 

你可以用一些不错的反弹效应在扩展这个功能动画初始化或进度变更。

http://jsfiddle.net/vL7Mp/2/

测试我只想简单地用一个upload.php的文件,就像Chrome浏览器

<?php 
print_r(array('file'=>$_FILE,'post'=>$_POST)); 
?> 

测试第一...然后应用必要的修改,与旧的浏览器使用。无论如何,此代码现在应该可以与所有最新的浏览器一起使用。

我明白,这个功能不是简单的理解等等......

如果您有任何问题,只是问。

也许有一些语法错误或缺少某些东西......因为我只是复制了整个函数并在运行中应用了一些更改。

一些其他有用的功能:

显示一个可读文件大小:

https://stackoverflow.com/a/20463021/2450730

转换MS到时间字符串或时间字符串MS

function ms2TimeString(a){ 
var ms=a%1e3>>0,s=a/1e3%60>>0,m=a/6e4%60>>0,h=a/36e5%24>>0; 
return (h<10?'0'+h:h)+':'+(m<10?'0'+m:m)+':'+(s<10?'0'+s:s)+'.'+(ms<100?(ms<10?'00'+ms:'0'+ms):ms); 
} 
function timeString2ms(a){ 
var ms=0,b; 
a=a.split('.'); 
!a[1]||(ms+=a[1]*1); 
a=a[0].split(':'),b=a.length; 
ms+=(b==3?a[0]*3600+a[1]*60+a[2]*1:b==2?a[0]*60+a[1]*1:s=a[0]*1)*1e3; 
return ms 
} 

一个简单的PAD LEFT功能

function padL(a,b,c){//string,length=2,char=0 
return (new Array(b||2).join(c||0)+a).slice(-b); 
} 

ps.i'm也在处理转换进度条。如果你感兴趣,我可以告诉你我的进步。

+0

好吧,这段代码似乎有效,但它对我来说很难理解javascript代码。我需要重写它,因为它似乎“print_r”当前文件没有在upload.php文件(我不知道为什么)specifiyng这一点。你不需要解决这个问题,我将不得不为自己找出答案。事情是我不明白为什么它在没有'行动=“”' - 标签的形式工作,我不明白为什么它使“print_r”。我也不明白为什么我不能使用'move_uploaded_file($ _ POST ['file'],'path/to/my/files');' – hardking

+0

这是html5新的FormData ..它不需要form.the内的任何属性print_r只是为了向你展示什么是上传。和有关PHP ...你可能有问题max_upload_size .. max_execution_time max_post_size ...或一些权限。 – cocco

+0

好吧,这很好的测试它在php.ini中的值,但它似乎有一个问题,执行upload.php时,无论我在哪里放脚本或如何设置路径,它doesnt调用文件,所以我不能使用POST-或FILE数据...我也尝试过一个新项目,其中所有文件都在同一个文件夹中,并且它不会加载小文件或大文件的“upload.php代码”文件,也许你会忘记一些东西来复制? (事先感谢,那真是太棒了!) – hardking

相关问题