Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seekbar does not work. #275

Open
onas opened this issue Mar 5, 2013 · 11 comments
Open

Seekbar does not work. #275

onas opened this issue Mar 5, 2013 · 11 comments
Labels

Comments

@onas
Copy link

onas commented Mar 5, 2013

Seekbar doesn't work when CherryMusic to play a flac file.
And the track length is 00:00.

Errorlog was not displayed.

@devsnd
Copy link
Owner

devsnd commented Mar 6, 2013

Thank you for the report! Unfortunately I cannot reproduce the error; I've streamed a flac file and I could seek within the file (at least as far as the file was already transcoded)

could you please provide additional information?

  • Which pyhton version are you using? try executing python --version to find out
  • Does the file otherwise play correctly?
  • Do you have installed the "stagger" module?
  • Where does the time display appear, that you report to show 00:00?
    (The display in the playlist depends additional meta-data which is fetched beforehand by the stagger module, while the display in the player depends on the actually streamed music data)

@onas
Copy link
Author

onas commented Mar 7, 2013

I will provide additional information.

  • Python 3.2.3
  • The flac file does not have the problem besides the problem that Seekbar does not move.Playback is decent.
  • mp3 files are no problem.
  • I have installed the "stagger" module.
  • I paste the install log.

    Download cherrypy now? (y/n)y

    You seem to be missing the optional module "stagger", an ID3-tag
    library. You should install it using the package manager of your OS.
    Alternatively cherrymusic can download it for you and put it in the
    folder in which cherrymusic resides.

    Download ID3-tag library stagger? (y/n)y
    Downloading cherrypy...
    Extracting /tmp/cherrypy.tar.gz
    Copying cherrypy module inside cherrymusic folder (/home/username/cherrymusic)...
    Cleaning up temporary files...
    Downloading stagger...
    /home/username/cherrymusic/stagger/__init__.py
    /home/username/cherrymusic/stagger/commandline.py
    /home/username/cherrymusic/stagger/conversion.py
    /home/username/cherrymusic/stagger/errors.py
    /home/username/cherrymusic/stagger/fileutil.py
    /home/username/cherrymusic/stagger/frames.py
    /home/username/cherrymusic/stagger/id3.py
    /home/username/cherrymusic/stagger/id3v1.py
    /home/username/cherrymusic/stagger/specs.py
    /home/username/cherrymusic/stagger/tags.py
    /home/username/cherrymusic/stagger/util.py
    done
    Successfully installed cherrymusic dependencies! You can now start cherrymusic.
  • That is displayed in the lower right corner of the seekbar.
  • I'm using Google Chrome browser.
    Please see the attached picture for details.

info

@devsnd
Copy link
Owner

devsnd commented Mar 7, 2013

I could now reproduce the problem. It is due to the way chrome handles an mp3 stream.

Firefox thinks of the stream as a unfinished download, so seeking is possible within the downloaded part of the audio. chrome thinks of it like an mp3-radio; It doesn't make sense to seek within a radio stream, since it is neverending, so chrome prevents that.

I'll try to find a solution, thanks again for the detailed report!

@Notmarrco
Copy link

I can confirm this issue, but with firefox 24.0
The seekbar does work when I don't use transcoding, but stop working when I activate it.
I have to say that I'm streaming over internet and my upload is very poor so perhaps firefox lacks the complete file when it starts playing.

@devsnd
Copy link
Owner

devsnd commented Oct 29, 2013

@Notmarrco, thanks for the report, but I can not reproduce this with firefox 24.

Is your server fast enough to transcode the file faster than the playback speed? And is the server upstream connection speed faster then the standard transcoding quality (160kbits for mp3 / 128kbits for ogg)?
(With firefox you can only seek within the already transcoded/cached parts of a track)

And also, what OS are you using?

EDIT: You can test the above by starting to play a transcoded track and then pausing. The track should then be cached and allow you to seek to another position.

@Notmarrco
Copy link

Good idea, I tried it then.
So the seekbar works, I can seek the position but the remaining time get stuck on 00.00 and I don't see the progressbar (one could have guess that :)). I don't understand why because the time played is good, the file is cached and the total track time is ok in the playlist view ...

@Notmarrco
Copy link

ok, I updated from squeeze to wheezy and installed python3, and updated to ff25, and it works.
Don't know which one of these updates did the trick though.

@devsnd
Copy link
Owner

devsnd commented Oct 30, 2013

Okay, so the problem is still only affecting chrome; Thanks for rechecking with up-to-date software.

We essentially also know how to fix the problem completely, but this is a rather complex issue. I tried to tackle from different sides multiple times; The easiest implementations either use up a lot of memory or disk space or just suck.

Anyway, I'll try to explain what's going on under the hood and why chrome doesn't play ball. Maybe someone takes this as a programming challenge 👯

WARNING: WALL OF TEXT! (mostly for developers)

Transcoding works like this:

A client requests a track from a special URL, which contains the original track and the desired transcoding format, e.g. http://localhost:8080/trans/this_is_the_track_i_need_to_transcode.flac/get.mp3

In the backend, this lets the audiotranscode module kick in. I starts a process usings pythons subprocess module that transcodes the FLAC file to MP3. The output of that process goes into a pipe, which can be read continuously.

This continous output (a generator, to be specific) is used in httphandler.py in the trans call and is directly handed back to the client. We've configured cherrypy so that it would not first gather all the data to send it back in one go, but to send chunks as they become available ("http streaming").

Now to the problem: Normally a HTTP response has a Content-Length header, which tells the browser how many bytes to expect to download. Unfortunately, we cannot know the exact length of the transcoded stream, before the transcoding process has ended. Depending on the hardware, the transcoding is just fast enough to allow for playback (e.g. raspberry pi), so this might take much to long to just transcode the file first and then sending the response once it's done.

This is all nice and good for firefox, since firefox assumes that the file is just at least as long as all the files it received so far. This is why you can only seek within the parts that are transcoded so far. This is not optimal, but not to bad either.

Chrome on the other hand assumes that a http stream (a http response without a length) is a neverending continous stream (like a internet radio) and should not be seekable. This can be overcome by giving chrome HTTP partial requests, since you can always reset the final content-length in a later packet, so we can trick chrome into behaving the same as firefox.

Is there a remedy?

What didn't quite work:

I've tried to estimate the length of encoded files, but I was always off by some bytes, which led to tracks being cut off at the end or the player hanging, because it still tried to receive the last non-existent bytes. Furthermore this leads to wrong time-length calculations on the client side.

What might work:

I tried to send HTTP partial requests and always send all the available data, but tell the browser that there is some more (lets say 10 bytes more) than I just handed over, so that the browser will request those 10 bytes when they are needed for playback. Once the transcoding is over, we can just tell the browser the real length. You could think of this approach as something like an adaptive estimate.

What would be the elegant and correct thing to do:

Always stream everthing; Files are no longer served staticly, but instead are always streamed. There is no notion of bytes or anything in the player: There is only time. So all the client needs to know is the file it wants to have and its length in seconds.
So playing a track at a certain time position would request file x at position 1:03 and the server would figure out where to start reading the file (and transcode it from there if necessary) and stream that to the client. The client would then blindly stream the file, play it back and just update the UI blindly. This would also allow for an easy implementation of #37.
Unfortunately this would mean that there had to be made big changes to jPlayer, which in turn means that we're not upstream compatible anymore, which means even more work in the end. It's a hard decision, even though it is self-evident that this would be a huge improvement.

And this is all I have to say about that. 📦 🍫

devsnd added a commit that referenced this issue Jan 13, 2014
devsnd referenced this issue in sn4kebite/cherrymusic May 27, 2014
This change adds support for cuesheets by passing a track parameter
around which indicates which track in the cuesheet should be played. The
actual audio file is split with ffmpeg using the -ss and -t parameters,
which are filled by the decoder when the file extension is '.cue'.

cuesheet.py is added to parse cuesheets. This is taken from a separate
project so it's a bit messy and contains some stuff that isn't used.

Metadata is also fetched from the cuesheet per track.
@Jaxkr
Copy link

Jaxkr commented Nov 23, 2015

I also have this issue, chrome.

@pando85
Copy link
Contributor

pando85 commented Dec 14, 2015

Same here with flac files:

  • Firefox 42.0 and chrome 46.0.2490.80 in linux (client).
  • Last CherryMusic version (0.36).

@TETYYS
Copy link

TETYYS commented Feb 12, 2017

same here with chrome, flac and mp3 won't seek

if you would go with estimating Content-Length solution, can you just send a length which guarantees that it would include all bytes and pad the excess with zeroes? Not sure if audio formats are happy with that..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants