2014-02-18 92 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

相關問題