Welcome Guest, Not a member yet? Register   Sign In
codeigniter + ajax + progressbar
#1

[eluser]codeplay[/eluser]
hello there!

i have this upload form which uploads a video to the server, encodes it (using FFMPEG), and puts it onto Amazon S3.

i have a jquery progressbar which shows the progress of the uploading+encoding process, by using ajax to do a GET request and to update it every 1/2 a second.

im setting the progress variable after each stage of the process.

the problem is it doesnt work as the data that is returned is always 'nothing'.

i just cant see what im doing wrong and whether the technique im using would work.

heres some of my code:

header.php (view)

Code:
function beginUpload() {
    var i = setInterval(function() {
        
        $.get('<?php echo base_url(); ?>upload/progress', function(data) {    
          $( "#uploadprogressbar" ).progressbar( "option", "value", parseInt(data) );
        });

    
     }, 500);
  }

$(document).ready(function(){

    $("#uploadform").submit(function () {
        beginUpload();
    });

     $("#uploadprogressbar").progressbar({value:0});
....

upload.php (controller)


Code:
class Upload extends Controller {

    public $progress;
    
    function Upload()
    {
        parent::Controller();
        $this->load->helper('url');
        $this->load->helper('form');
        $this->load->library('form_validation');
    
        $this->load->model('Video');
    }
    
    function index()
    {    
        $this->processupload();
    }
    

    function processupload()
    {    
                
        $data['page_title'] = "Upload";
        //validation stuff omitted
        
        $this->form_validation->set_error_delimiters('<div class="form_error">', '</div>');
        
        
        if ($this->form_validation->run() == FALSE)
        {
    
            $this->load->view('header', $data);
            $this->load->view('upload');
            $this->load->view('footer');
            
        } else {
            
            $uniq_id = time();
            
            $this->setprogress(10);
            $error = $this->do_upload($uniq_id);
            
            
            if($error == "")
            {
                $this->setprogress(90);
                $video_data = array(
                    'user_id'    => $user_id,
                    'sport_cat' => $this->input->post('sport_cat'),
                    'competition_cat' => $this->input->post('competition_cat'),
                    'title' => $this->input->post('title'),
                    'description' => $this->input->post('description'),
                    'tags' => $this->input->post('tags'),
                    'uniq_id' => $uniq_id
                );
            
            
                $this->Video->add($video_data);  
                
                $this->setprogress(100);
                redirect(base_url());
            } else {
            
                $data['uploaderror'] = '<div class="form_error">'.$error.'</div>';
                
                $this->load->view('header', $data);
                $this->load->view('upload', $data);
                $this->load->view('footer');
                
            }
        }
    }    
    
    function do_upload($uniq_id)
    {
        $config['upload_path'] = 'assets/videos/temp/';
        $config['allowed_types'] = 'wmv';
        $config['max_size']    = '50000';
        $config['file_name'] = $uniq_id.".wmv";
        
        $this->load->library('upload', $config);
    
        
        $error = "";
        $this->setprogress(20);
        if ( ! $this->upload->do_upload('upload_video'))
        {
            $error = $this->upload->display_errors();
            //print_r($config);
        }
        else
        {
            $this->setprogress(30);
            $data = $this->upload->data();
            $this->setprogress(40);
            echo exec("ffmpeg -i "."assets/videos/temp/".$data['file_name']." -ar 22050 -ab 32 -f flv -s 480x360 "."assets/videos/temp/".$data['raw_name'].".flv");
            $this->setprogress(60);
            //include the S3 class
            if (!class_exists('S3'))require_once('S3.php');

            //AWS access info
            if (!defined('awsAccessKey')) define('awsAccessKey', 'xxx');
            if (!defined('awsSecretKey')) define('awsSecretKey', 'xxx');

            //instantiate the class
            $s3 = new S3(awsAccessKey, awsSecretKey);

            
            //move the file
            if (!$s3->putObjectFile("assets/videos/temp/".$data['raw_name'].".flv", "xxx", $data['raw_name'].".flv", S3::ACL_PUBLIC_READ)) {
                $error ="Something went wrong while uploading your file...";
            }
            $this->setprogress(80);
            
        }
        
        return $error;
    }    
    

    
    function setprogress($value)
    {
        $this->progress = $value;
    }
    
    function progress()
    {
        echo $this->progress;
    }

.........

all help and advice will be greately appreciated! thank you
#2

[eluser]cahva[/eluser]
You cannot do it like that. When you query upload/progress url it is totally separate from your current serverside actions and it doenst know any variables or what has happened before or is happening atm.

One solution is to write the progess to a file(with unique name ofcourse) and the upload/progress function will read that file.
#3

[eluser]codeplay[/eluser]
i see... thanks about that. i tried storing the progress variable in a session and reading it with ajax, but it still doesnt work.

i was also thinking storing the progress in a db table but storing it to a text file will be better.
#4

[eluser]codeplay[/eluser]
hey man, i tried to write the progress to a file and then read it using ajax, but the progressbar is not moving at all. the reponse i get is still nothing...

here are my new functions:

Code:
function progress()
    {
        $res = read_file('assets/videos/temp/'.$this->progress_name.'.txt');
        echo $res;
    }
    
    function set_progress($val)
    {
        write_file('assets/videos/temp/'.$this->progress_name.'.txt', $val);
    }

any ideas?
#5

[eluser]cahva[/eluser]
Where does the $this->progress_name come from(doest progress method know about it)? Is it really writing to the file?
#6

[eluser]codeplay[/eluser]
It's basically initialised in the constructor with the time() function and yes it is writing to the file. I checked and there is always the value 100. I've used firebug to debug and the response that I get when running the Ajax get request is always nothing for some reason.
#7

[eluser]cahva[/eluser]
Well do a little debug then..
Code:
function progress()
{
    $f =  'assets/videos/temp/'.$this->progress_name.'.txt';
    if (file_exists($f))
    {
        echo read_file($f);
    }
    else
    {
        echo 'Error: "'.$f.'" doesnt exist!';
    }
}

Check the output with firebug. I think the problem could be that you use time() as that will change(file wont be the same name after initializing). Remember, the constructor for the normal http- and ajax-request are not executed at the same time!

Maybe store the filename to session?
#8

[eluser]codeplay[/eluser]
hey thanks man, i did what you suggested and it works! i also used the rand() function to initialise it in the pogress variable.

the thing is now that the progress bar goes up to a 100 in a second but the process is still not finished.. might consider using swf upload or something.




Theme © iAndrew 2016 - Forum software by © MyBB