Go
Not registered? Sign up!

Pseudo streaming and seeking

Google Translate
16 posts | return to the Setup Problems forum | get the rss feed for this thread

Oct. 25, 2009Jim

I'm having trouble with pseudo streaming. When moving the cursor to seek it jumps back to 0 and starts playback from the beginning even if the place I'm trying to jump is buffered or not.

Following is my code to embed the player using SWFObject 3.2.

var plugins = 'hd-1,quickkeys-1';
if (playlist[item]['video'] != '1') { // This is audio only. Give the user some eye-candy =)
plugins += ',spectrumvisualizer-1';
}
var flashvars = { // Look at how lovely this is compared to SWFObject 1.x <3
'backcolor':'#555555',
'frontcolor':'#ffffff',
'lightcolor':'#ffffff',
'controlbar':'over',
'skin':'player/bekle.swf',
'plugins':plugins,
'volume':'100',
'streamer':'../stream.php',
'file':encodeURIComponent(path),
'hd.file':encodeURIComponent(path + '&hd=1'),
'duration':duration,
'type':'http'
};
var params = {
'allowscriptaccess':'always',
'allowfullscreen':'true'
};
var attributes = {
'id':playerId,
'name':playerId
};
swfobject.embedSWF('player/player.swf',playerId,'100%','337','8','express.swf',flashvars,params,attributes);

Oct. 25, 2009hobbs

 
First, let's straighten out some "things" in your player code.

1) Wrong format for the "color" flashvars.

2) You need to use a full URI for the value of the streamer flashvar.

3) Use the flashvar id for your Linux users.

4) The id of the HTML element that swfobject writes the object element to should be different than the player's id.

  var plugins = 'hd-1,quickkeys-1';

  if (playlist[item]['video'] != '1') { // This is audio only. Give the user some eye-candy =)
    plugins += ',spectrumvisualizer-1';
  }

  var flashvars = { // Look at how lovely this is compared to SWFObject 1.x <3
    'backcolor':              '555555',
    'frontcolor':             'ffffff',
    'lightcolor':             'ffffff',
    'controlbar':             'over',
    'skin':                   'player/bekle.swf',
    'plugins':                 plugins,
    'volume':                 '100',
    'streamer':               'http://www.domain.com/path/stream.php',
    'file':                    encodeURIComponent(path),
    'hd.file':                 encodeURIComponent(path + '&hd=1'),
    'duration':                duration,
    'id':                      playerId,
    'type':                   'http'
  };

  var params = {
    'allowscriptaccess':      'always',
    'allowfullscreen':        'true'
  };

  var attributes = {
    'id':                      playerId,
    'name':                    playerId
  };

  swfobject.embedSWF('player/player.swf', player, '100%', '337', '8', 'express.swf', flashvars,params,attributes);


Your FLV video container file must have the array of time/byte-position metadata to use pseudostreaming.

You can check the metadata with flvdump from: http://code.google.com/p/flvmeta/

You can use FLVMDI, flvtool2, flvtool++, yamdi, flvmeta, or other tools to create and inject the metadata array.

Using Live HTTP Headers for Firefox or ieHTTPHeaders for Internet Explorer, you should see requests that look like:
http://www.domain.com/path/stream.php?file=video.flv&start=12345

Oct. 25, 2009Jim

I've fixed the things you list, but I think my problem is that my FLV files are created on the fly my FFMPEG (transcoded when requested). I'm guessing the resulting stream doesn't have the metadata you mention. Do you know anything about this?

EDIT: My browsers don't make new requests when I seek. I'm using Firebug for firefox and my access log to check this.

EDIT2: Please note that SWFObject 2.x replaces the object you give the ID of, instead of inserting the SWF inside it like SWFObject 1.x did.

Oct. 25, 2009hobbs

If you are using ffmpeg to create the video, you must pipe it through flvtool2 to create and inject the metadata. It's the only metadata injector that has full piping in & out.

http://inlet-media.de/flvtool2


C:\Program Files\LightTPD-1.4.22-1\htdocs>flvtool2 -H
FLVTool2 1.0.6
Copyright (c) 2005-2007 Norman Timmler (inlet media e.K., Hamburg, Germany)
Get the latest version from http://www.inlet-media.de/flvtool2
This program is published under the BSD license.

Usage: flvtool2.exe [-ACDPUVaciklnoprstvx]... [-key:value]... in-path|stdin [out
-path|stdout]

If out-path is omitted, in-path will be overwritten.
In-path can be a single file, or a directory. If in-path is a directory,
out-path has to be likewise, or can be omitted. Directory recursion
is controlled by the -r switch. You can use stdin and stdout keywords
as in- and out-path for piping or redirecting.


Chain commands like that: -UP (updates FLV file than prints out meta data)

Commands:
-A Adds tags from -t tags-file
-C Cuts file using -i inpoint and -o outpoint
-D Debugs file (writes a lot to stdout)
-H Helpscreen will be shown
-P Prints out meta data to stdout
-U Updates FLV with an onMetaTag event

Switches:
-a Collapse space between cutted regions
-c Compatibility mode calculates some onMetaTag values different
-key:value Key-value-pair for onMetaData tag (overwrites generated values)
-i timestamp Inpoint for cut command in miliseconds
-k Keyframe mode slides onCuePoint(navigation) tags added by the
add command to nearest keyframe position
-l Logs FLV stream reading to stream.log in current directory
-n Number of tag to debug
-o timestamp Outpoint for cut command in miliseconds
-p Preserve mode only updates FLVs that have not been processed
before
-r Recursion for directory processing
-s Simulation mode never writes FLV data to out-path
-t path Tagfile (MetaTags written in XML)
-v Verbose mode
-x XML mode instead of YAML mode

REPORT BUGS at http://projects.inlet-media.de/flvtool2
Powered by Riva VX, http://rivavx.com



Yes, I know all about swfobject v2.2 writing the object element to outerHTML rather than to innerHTML like v1.5 did. I've posted that a thousand times on this Forum. The default is to use the id that is in the embedSWF() code, but that runs into problems, so it's best to use something else for the player's id and the name/id attributes of the object element.
.

Oct. 25, 2009hobbs

A snippet of PHP code using ffmpeg and flvtool2.
passthru("ffmpeg.exe -ss {$start} -t {$duration} -i \"{$filepath}\" -sameq -r 20 -g 200 -async 1 - | flvtool2 -U stdin stdout");

Oct. 25, 2009Jim

This is what I've got

system('ffmpeg -y -i ' . escapeshellarg($path) . $custom_start . ' -ar 44100 -ab ' . $audio_bitrate . 'k -vb ' . $video_bitrate . 'k -f flv - | flvtool2 -U stdin stdout');

It gives me the following output

FFmpeg version 0.5, Copyright (c) 2000-2009 Fabrice Bellard, et al.
configuration: --enable-gpl --enable-postproc --enable-swscale --enable-avfilt
er --enable-avfilter-lavf --enable-pthreads --enable-avisynth --enable-libfaac -
-enable-libfaad --enable-libmp3lame --enable-libspeex --enable-libtheora --enabl
e-libvorbis --enable-libxvid --enable-libx264 --enable-memalign-hack
libavutil 49.15. 0 / 49.15. 0
libavcodec 52.20. 0 / 52.20. 0
libavformat 52.31. 0 / 52.31. 0
libavdevice 52. 1. 0 / 52. 1. 0
libavfilter 0. 4. 0 / 0. 4. 0
libswscale 0. 7. 1 / 0. 7. 1
libpostproc 51. 2. 0 / 51. 2. 0
built on Mar 16 2009 16:09:18, gcc: 4.2.4 [Sherpya]

Seems stream 0 codec frame rate differs from container frame rate: 24.01 (65535/
2730) -> 24.00 (24/1)
Input #0, avi, from 'F:\Multimedia\Video\Music videos\AMVs\82Ideas_Azumerica.avi
':
Duration: 00:04:14.50, start: 0.000000, bitrate: 2617 kb/s
Stream #0.0: Video: mpeg4, yuv420p, 640x480 [PAR 1:1 DAR 4:3], 24 tbr, 24 tb
n, 24.01 tbc
Stream #0.1: Audio: mp3, 44100 Hz, stereo, s16, 192 kb/s
Output #0, flv, to 'pipe:':
Stream #0.0: Video: flv, yuv420p, 640x480 [PAR 1:1 DAR 4:3], q=2-31, 4096 kb
/s, 90k tbn, 24 tbc
Stream #0.1: Audio: libmp3lame, 44100 Hz, stereo, s16, 256 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Stream #0.1 -> #0.1
Press [q] to stop encoding
ERROR: File has to contain at least 2 video tags to calculate frame sequence
ERROR: flv/stream.rb:252:in `frame_sequence'
ERROR: flv/stream.rb:270:in `framerate'
ERROR: flv/stream.rb:131:in `add_meta_tag'
ERROR: flvtool2/base.rb:184:in `add_meta_data_tag'
ERROR: flvtool2/base.rb:137:in `update'
ERROR: flvtool2/base.rb:47:in `send'
ERROR: flvtool2/base.rb:47:in `execute!'
ERROR: flvtool2/base.rb:46:in `each'
ERROR: flvtool2/base.rb:46:in `execute!'
ERROR: flvtool2/base.rb:206:in `process_files'
ERROR: flvtool2/base.rb:44:in `execute!'
ERROR: flvtool2.rb:168:in `execute!'
ERROR: flvtool2.rb:228
av_interleaved_write_frame(): Error while opening file

Oct. 26, 2009hobbs

This is what I use to transcode from AVI to FLV:
ffmpeg -i "%1.avi" -threads 2 -s 320×240 -r 20 -threads 1 -pix_fmt yuv420p -g 40 -qmin 3 -b 384k -async 50 -acodec libmp3lame -ar 22050 -ac 1 -ab 96k -y "%1.flv" 2>"%1.txt"

:: where:

:: -i "%1.avi":        Input filename 
:: -threads 2:         Thread count 
:: -s 320×240:         Frame size (evenly divisible by 16)
:: -r 20:              Frame rate (fps) 
:: -threads 1:         Thread count (again) 
:: -pix_fmt yuv420p:   Pixel format 
:: -g 40:              Group of pictures size (keyframe interval)
:: -qmin 3:            Minimum video quantizer scale (VBR) 
:: -b 512k:            Video bitrate in bits/s 
:: -async 50:          Audio sync method. “Stretches/squeezes” the audio stream to match the timestamps, the parameter is the maximum samples per second by which the audio is changed. 
:: -acodec libmp3lame: Force audio codec to codec 
:: -ar 22050:          Audio sampling frequency 
:: -ac 1:              Audio channels 
:: -ab 16k:            Audio bitrate in bits/s 
:: -y:                 Overwrite output files 
:: "%1.flv":           Output filename

Oct. 26, 2009Jim

The FFMPEG command doesn't seem to be the issue. It looks to me as if there is some kind of bug when using FFMPEG and FLVTool2 in conjuction.

Passing the output from FFMPEG to a file and then running FLVTool2 on that works, but piping does not.

Oct. 26, 2009hobbs

Hmmmm....

Something caused me to assume that you were on a *nix system.

Now that I look a bit closer, I see the drive letters and the backslashes of Windows.

You can't pipe on Windows with flvtool2, so dumping ffmpeg to a temp file, then processing with flvtool2 is the only way. A while ago, I spent a long time looking for a metadata creator/injector that could pipe on Windows, but I never found one. Apparently piping on Windows is difficult/broken. I usually cache the output so it never has to be generated again, but that depends on the nature of your video usage. You can also do H.264/MP4 video the same way because ffmpeg won't output H.264/MP4 "live".

If you want PHP for snipping & caching, I have some tested and proven scripts.

Oct. 26, 2009Jim

Hm.. Wouldn't it be possible to do this with PHP's popen()?

EDIT: No. Seems flvtool2 is just not up to it. Does it require the whole file to be cached before it can work?

Oct. 26, 2009hobbs

Yes, I believe that ffmpeg has to be finished before flvtool2 can do its thing, when you're not piping. Too bad piping is so messed up on Windows. I know it can be done, because I've used other programs that pipe, but apparently it's hard to implement, so the flvtool2 developers didn't bother. No other metadata creator/injector can pipe in/out.

The way I used ffmpeg/flvtool2 was to clip little snippets out of a video with a precise starting point regardless of whether or not there was a keyframe at that time. Since the snippets were in a playlist that was used repeatedly, it made sense to cache the snippets for later use. All it took to fill the cache was to automatically play the entire playlist once.

Maybe if you describe what you're trying to do, I can suggest another solution???

Oct. 27, 2009Jim

This project is what you'd call a closed beta. If you mail me at "jckf at jimckf.com" I can link you to it so that you can understand what it is I am doing.

Oct. 30, 2009kisscool82

I'm sorry to post here, but I cannot post a new message 'cause of an php error :
Fatal error: Call to undefined method MDB2_Error::bindParam() in /var/www/vhosts/www1.longtailvideo.com/httpdocs/jw/include/post.php on line 129

I'm trying to use http pseudo streaming (h264 module for apache).
My installation seems to work, but there's a problem with the player.
I read the documentation and add the type and http.startparam flashvars, but the player does'nt work anymore... It seems to load something but never finish the initialisation.

Here's my code :

<div style='display:none;' id='video'>

<script type="text/javascript">
var flashvars = {
file: "http://h264.code-shop.com:8080/workers_world_co64_box64.mp4",
id: "video",
repeat: "list",
backcolor: "eeeeee",
frontcolor: "161618",
dock: false,
type: "http",
"http.startparam": "start"
};

var params = {
wmode: "opaque",
allowfullscreen: true,
allowscriptaccess: "always"
};
var attributes = {
id: "video",
name: "video"
};
swfobject.embedSWF("player-viral.swf", "video", "700", "360", "9","expressInstall.swf", flashvars, params, attributes);

</script>


When I delete these 2 lines, the player works perfectly but there's no streaming...

type: "http",
"http.startparam": "start",


Does anybody can help me please ?

Oct. 30, 2009hobbs

 
Streams, plays, and seeks for me:

  <head>

    <script src="http://www.google.com/jsapi"></script>

    <script>
      google.load('swfobject', '2.2');
    </script>

    <script type="text/javascript">
      var flashvars =
      {
        'file':                        'http://h264.code-shop.com:8080/workers_world_co64_box64.mp4',
        'type':                        'http',
        'http.startparam':             'start',
        'dock':                        'false',
        'backcolor':                   'EEEEEE',
        'frontcolor':                  '161618',
        'id':                          'video',
        'autostart':                   'true'
      };

      var params =
      {
        'allowscriptaccess':           'always',
        'allowfullscreen':             'true'
      };

      var attributes =
      {
        'id':                          'video',
        'name':                        'video'
      };

      swfobject.embedSWF('player.swf', 'player', '700', '360', '9.0.124', false, flashvars, params, attributes);
    </script>

  </head>

  <body>

    <div id="playercontainer" class="playercontainer"><a id="player" class="player" href="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash">Get the Flash Plugin to see this video.</a></div>

  </body>

Oct. 30, 2009kisscool82

I've replace viral player with classic player and now your exemple works.
But when I replace the file flashvarr with my playlist, the player shows me : "video not find : playlist.xml"

How can I do ?

<head>

<script src="http://www.google.com/jsapi"></script>

<script>
google.load('swfobject', '2.2');
</script>

<script type="text/javascript">
var flashvars =
{
'file': 'playlist.xml',
'type': 'http',
'http.startparam': 'start',
'dock': 'false',
'backcolor': 'EEEEEE',
'frontcolor': '161618',
'id': 'video',
'autostart': 'true'
};

var params =
{
'allowscriptaccess': 'always',
'allowfullscreen': 'true'
};

var attributes =
{
'id': 'video',
'name': 'video'
};

swfobject.embedSWF('player.swf', 'player', '700', '360', '9.0.124', false, flashvars, params, attributes);
</script>

</head>

<body>

<div id="playercontainer" class="playercontainer"><a id="player" class="player" href="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash">Get the Flash Plugin to see this video.</a></div>

</body>


<?xml version="1.0" encoding="utf-8"?>
<playlist version="1" xmlns="http://xspf.org/ns/0/">
<title>Exemple de tracklist XML</title>
<info>http:/xspf.org/xspf-v1.html</info>
<trackList>
<track>
<title>Title</title>
<location>http://h264.code-shop.com:8080/workers_world_co64_box64.mp4</location>
</track>
</trackList>
</playlist>


Thanks

Oct. 30, 2009hobbs


var flashvars =
{
'file': 'playlist.xml',
'type': 'http',
'http.startparam': 'start',
'dock': 'false',
'backcolor': 'EEEEEE',
'frontcolor': '161618',
'id': 'video',
'autostart': 'true'
};



<?xml version="1.0" encoding="utf-8"?>
<playlist version="1" xmlns="http://xspf.org/ns/0/">
<title>Exemple de tracklist XML</title>
<info>http:/xspf.org/xspf-v1.html</info>
<trackList>
<track>
<title>Title</title>
<location>http://h264.code-shop.com:8080/workers_world_co64_box64.mp4</location>
<meta rel="type">http</meta>
</track>
</trackList>
</playlist>

Add a reaction

You can also return to the category or try this search for related threads.


 

Search the Forums

Go

Support

Support Here are some helpful links to learn more about the JW Player™:

Monetize Your Video

Monetize Your Video Earn money with ads from LongTail's AdSolution. Watch our demos and sign up now!

Why Buy a License?

Why Buy a License? If you don’t buy a commercial license, you cannot use a JW Player™ on (i) a site that has ads; (ii) a corporate site; or a (iii) CMS. Our licenses are very inexpensive, so what are you waiting for? Buy a license today.