[PHP/JS] Videobestand streamen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Hmail
  • Registratie: April 2003
  • Laatst online: 15-09 10:50

Hmail

Doet ook maar wat.

Topicstarter
De situatie is als volgt:
Voor een systeem wat ik aan het schrijven ben is het de bedoeling dat de videobestanden via een FLV player worden afgespeeld. Daarnaast is het niet de bedoeling dat de gebruiker niet te zien krijgt waar de FLV bestanden zijn opgeslagen, hoe ze heten, etc.
Kortom, de bedoeling is dat PHP de FLV bestanden aanlevert, in plaats van http://localhost/upload/video/video.flv zou het dan http://localhost/video.php?id=1 moeten worden. Het lijkt mij dat ik PHP gewoon de opdracht kan geven om een FLV bestand uit te spugen, en dat vervolgens als argument aan een FLV player mee te geven.
Mijn code:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    function stream() {
        $file = $this->config['root']['path']."upload\\video\\".$this->filename;
        if(isset($_GET['pos'])) {
            $pos = $_GET['pos'];
        } else {
            intval($_GET['pos']);
        }
        header("Content-Type: video/x-flv");
        header("Content-Length: ".filesize($file));
        if($pos > 0) {
            echo "FLV";
            echo pack("C", 1);
            echo pack("C", 1);
            echo pack("N", 9);
            echo pack("N", 9);
        }
        $handle = fopen($file, "rb");
        fseek($handle, $pos);
        fpassthru($handle);
        fclose($handle);
    }

Dit levert een werkend flv bestand op. Als ik de output hiervan opsla, en afspeel met iets als Media Player Classic werkt het gewoon. Het probleem lijkt dan ook in de javascript van de JW FLV Media Player te liggen. Alleen: Wat doe ik fout?
De javascript code:
code:
1
2
3
4
5
6
7
8
    <script type="text/javascript">
        var s1 = new SWFObject("mediaplayer.swf","mediaplayer","300","185","8");
        s1.addParam("allowfullscreen","true");
        s1.addVariable("width","300");
        s1.addVariable("height","185");
        s1.addVariable("file", "video.php?id=1");
        s1.write("container");
    </script>

Als ik dit uitvoer krijg ik een media player te zien, maar als ik op Play klik blijft het scherm zwart, en word er niks afgespeelt. Ik kan die player ook niet echt lekker debuggen, dus waar het precies mee te maken heeft weet ik niet.

Via Google kom ik op de term 'streamscript' die ik als variabele mee kan geven aan de player, en de code daarvan heb ik ook deels overgenomen in de php code, alleen ook dan krijg ik het niet afgespeelt.

Iemand die me op weg kan helpen?

It might sound as if I have no clue what I'm doing, but I actually have a vague idea.


Acties:
  • 0 Henk 'm!

  • ValHallASW
  • Registratie: Februari 2003
  • Niet online
Probeer eens met een packet sniffer te kijken wat er precies wordt opgevraagd; wellicht is het iets stoms als het urlencoden van de ? en =. (in dat geval moet je op een andere manier je data doorspelen; bv. video.php/1 of iets dergelijks)

Los daarvan: wat denk je ermee te bereiken door je file vanuit een phpscript aan te leveren? Dan kan je namelijk prima de output daarvan opslaan...

Acties:
  • 0 Henk 'm!

  • Hmail
  • Registratie: April 2003
  • Laatst online: 15-09 10:50

Hmail

Doet ook maar wat.

Topicstarter
Uit de packet sniffer haal ik niets bijzonders, gewoon wat ik opgevraagd heb. Als ik de apache access logs bekijk valt me wel iets op, maar niet iets bijzonders. In plaats van dat video.php?id=1 word opgevraagd, neemt hij video.php?id=7&<insert random nummer>. Als ik dat overneem download hij wel gewoon het bestand. Dat lijkt het dus niet te zijn.

En zoals ik al zei: Het is de bedoeling dat de gebruiker niet kan zien waar de flv bestanden zich bevinden en hoe ze heten. Daarnaast is een bijkomend voordeel dat ik geen extra moeite hoef te doen voor de authorisatie, omdat dit al in de rest van het systeem is verwerkt.
Het is grotendeels de vraag van de klant, wat voordeel voor mij, en nu vooral omdat ik het werkend wil krijgen :)

It might sound as if I have no clue what I'm doing, but I actually have a vague idea.


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Probeer het anders zo eens

PHP:
1
2
3
4
5
6
7
8
9
<?php
        $file = '/pathto/videos/'.$id.'.flv';
        header("Content-Type: video/x-flv");
        header('Content-Length: ' . filesize($file));
        $fh = fopen($file,"rb");
        fseek($fh, $pos);
        while (!feof($fh)) { print(fread($fh, filesize($file))); }
        fclose($fh);
?>


Deze werkt perfect bij de JW player

Acties:
  • 0 Henk 'm!

  • Hmail
  • Registratie: April 2003
  • Laatst online: 15-09 10:50

Hmail

Doet ook maar wat.

Topicstarter
Helaas, hetzelfde resultaat. Niets dus.

Dat lijkt er toch op dat ik het verkeerd doe bij de JW FLV Player. Heb je misschien daar voorbeeldcode van, waaraan ik kan zien of ik het verkeerd doe?

edit:
Na een dag klussen en frustraties, het probleem de uitdaging is opgelost *O*
Het bleek inderdaad in de javascript code te zitten. Het probleem zit er in dat als je niet opgeeft welk type bestand je af wilt spelen, het script de laatste 3 tekens van 'file' neemt, en daar het type aan bepaalt. Aangezien dat in mijn geval video.php?id=1 was kon hij daar niets mee.
Door slechts op te geven welk type het was bleek het probleem opgelost. Hier nog even voor de volledigheid de huidige code (speelt geen grotere bestanden af, dus de code is niet perfect):

code:
1
2
3
4
5
6
7
8
9
10
    <script type="text/javascript">
        var s1 = new SWFObject("mediaplayer.swf","mediaplayer","300","185","8");
        s1.addParam("allowfullscreen","true");
        s1.addVariable('type','flv');
        s1.addVariable("width","300");
        s1.addVariable("height","185");
        s1.addVariable("file", "video.php?id=2");
        s1.addVariable("bufferlength","10");
        s1.write("container");
    </script>


edit2:
En dan nu ook grotere bestanden kunnen weergeven *O* :
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    function stream() {
        ini_set("memory_limit","800M"); // via filesize() laten bepalen is mooier.
        $file = $this->config['root']['path']."upload\\video\\".$this->filename;
        $fh = fopen($file,"rb");
        if(!$fh) {
            echo 'fout!';
            die();
        }
        fseek($fh, 0);
        $i = "";
        header("Content-Type: video/x-flv");
        header("Content-Length: ".filesize($file)); 
        while (!feof($fh)) { 
            $buffer = fgets($fh, 4096);
            echo $buffer;
        }
        fclose($fh); 
    }

[ Voor 92% gewijzigd door Hmail op 12-05-2008 00:06 ]

It might sound as if I have no clue what I'm doing, but I actually have a vague idea.


Acties:
  • 0 Henk 'm!

  • Borizz
  • Registratie: Maart 2005
  • Laatst online: 24-08 20:35
Hmail schreef op zondag 11 mei 2008 @ 21:13:

edit2:
En dan nu ook grotere bestanden kunnen weergeven *O* :
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    function stream() {
        ini_set("memory_limit","800M"); // via filesize() laten bepalen is mooier.
        $file = $this->config['root']['path']."upload\\video\\".$this->filename;
        $fh = fopen($file,"rb");
        if(!$fh) {
            echo 'fout!';
            die();
        }
        fseek($fh, 0);
        $i = "";
        header("Content-Type: video/x-flv");
        header("Content-Length: ".filesize($file)); 
        while (!feof($fh)) { 
            $buffer = fgets($fh, 4096);
            echo $buffer;
        }
        fclose($fh); 
    }
Ehm het voordeel van iets streamen zou moeten zijn dat je het niet helemaal in het geheugen hoeft te plaatsen en jij zet de memory_limit op 800M..?? Je huidige script heeft echt niet zoveel geheugen nodig, alles wordt toch al per 4096 bytes gelezen en geprint.
Je zou nogeens kunnen kijken naar de PHP functie fpassthru, dat scheelt weer een paar regels code.

If I can't fix it, it ain't broken.


Acties:
  • 0 Henk 'm!

  • Hmail
  • Registratie: April 2003
  • Laatst online: 15-09 10:50

Hmail

Doet ook maar wat.

Topicstarter
Je hebt gelijk, die hoorde daar niet meer. Het was al laat :P
Naar fpassthru ga ik nog even kijken, bedankt :)

It might sound as if I have no clue what I'm doing, but I actually have a vague idea.

Pagina: 1