0

I have a problem for my website. I try to put a video streaming on my website. This part works good. I used this topic to make my code: Symfony2 video streaming.

I use an external video file and not a local file, but it works.

But until the video isn't completely loaded for the client, I can't make any request (for example, post a comment or go to another page (even if the action will break the streaming to go to another page)). I tried the stream_context_create function but I don't understand how it works.

I don't know how to do to "delegate" the streaming and continue the navigation.

Can you help me please, because the client is blocked until his video is loaded.

Community
  • 1
  • 1
Lerminou
  • 158
  • 1
  • 8

2 Answers2

0

I would wrap your streaming logic into Symfony console command and launch the daemon with upstart or bash script. You can interact with daemon using tasks in Redis or Mysql.

UPD: Create Task entity in AppBundle/Entity folder:

<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
 * @ORM\Entity
 * @ORM\Table
 */
class Task
{   
    /**
     * @ORM\Id
     * @ORM\Column(type="bigint")
     * @ORM\GeneratedValue(strategy="AUTO")
     * @var int
     */
    private $id;    
    /**
     * @ORM\Column(type="text")
     * @var string
     */
    private $fileName;
    /**
     * @var boolean
     * @ORM\Column(type="string", length=50)
     */
    protected $status = 'new';
    /**
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }
    /**
     * @param string $status
     */
    public function setStatus($status)
    {
        $this->status = $status;
    }
    /**
     * @return string
     */
    public function setStatus($status)
    {
        return $this->status;
    }
}

Update database schema and ensure that table has been created:

app/console doctrine:schema:update --force

Create Symfony Command.

namespace AppBundle\Command;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class VideoDaemonCommand extends ContainerAwareCommand
{
    protected function configure()
    {
        $this->setName('app:video-daemon');
    }

    /** @var EntityManager */
    private $em;

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->em = $this->getContainer()->get('doctrine.orm.entity_manager');
        while (true) {
            $task = $this->em->getRepository('AppBundle:Task')->findOneBy(['status' => 'new']);
            if (is_null($task)) {
                sleep(5);
                continue;
            }
            $this->setTaskStatus('processing', $task);
            $this->processTask($task);
        }
    }

    private function processTask($task) {
        //here do streaming logic
        $this->setTaskStatus('completed', $task);
    }

    private function setTaskStatus($status, $task) {
        $task->setStatus($status);
        $this->em->persist($task);
        $this->em->flush();
    }
}

Lets create a daemon with upstart(debian/ubuntu). Place the following content to into /etc/init/video-daemon.conf and restart computer.

start on filesystem or runlevel [2345]
stop on runlevel [!2345]

### Keep the process alive, limit to 5 restarts in 60s

  respawn
  respawn limit 5 60

### Start daemon

script
  exec /path/to/your/project/app/console app:video-daemon
end script

Check if daemon works:

ps -aux | grep video-daemon

Now if everything gone well you can create tasks in Symfony controllers/services by:

$task = new \AppBundle\Entity\Task();
$em->persist($task);
$em->flush();
karser
  • 1,365
  • 2
  • 13
  • 23
  • Hi, thanks for your answer. Do you have any example or links to help me ? I'm a little newbie to symfony and i don't know how to interact with the console and the daemon tasks can respons to the client throught mysql? – Lerminou Jul 18 '15 at 21:34
  • Thanks, i can now create tasks and execute them but i still have a question, how the command can return the content to my client ? because the controller will only create the task. From my twig, did i need a render controller ? for my balise – Lerminou Jul 19 '15 at 10:23
  • You can perform ajax request (/check-task/{task_id}) the server 1-2 times in minute to check if the task is ready. If it is ready, you can make video request and return content to your client. Please accept my answer if you find it correct. Thanks! – karser Jul 19 '15 at 11:09
  • I accepted your answer because it helped me a lot. but if I make a video request my problem will be the same no ? : until the content isn't downloaded, i can't make another request. And the video will be charged in memory so if many clients want to load a video, I think my server won't support large files. – Lerminou Jul 19 '15 at 12:10
  • Video streaming performs not under nginx, so it's not inluence your requests. Parallels requests works well in nginx, don't worry. Use additional servers to process tasks and delivery video content. – karser Jul 19 '15 at 12:53
  • Oh, but ... i'm using apache :( maybe it's the problem. because, i see in the console in chrome: my streaming request is 'pending' so my other request is queued. for example , a sub domain that will perform these streamings ? sry for all my questions ... – Lerminou Jul 19 '15 at 13:02
  • I think it's Chrome issue. First try reproduce the same bug in firefox. – karser Jul 19 '15 at 13:45
  • Nginx uses less memory when handles static content. So switch to Nginx on production is a good idea. – karser Jul 19 '15 at 13:46
  • Anyway I proposed you a good pattern of tasks usage. You can scale this approach on many servers. – karser Jul 19 '15 at 13:51
  • Ok i will try this. Thanks a lot karser – Lerminou Jul 19 '15 at 15:26
0

I found the real problem : it works good on FF but in Chrome, the request stays in pending.

i needed to add a timestamp parameter to my request to force Chrome to re-download the page

topic : HTML5 video element request stay pending forever (on chrome)

Community
  • 1
  • 1
Lerminou
  • 158
  • 1
  • 8