Home of the Squeezebox™ & Transporter® network music players.
Results 1 to 6 of 6
  1. #1
    Junior Member
    Join Date
    Mar 2010
    Location
    Costa Rica
    Posts
    20

    Trouble seeking into a remote track

    Hi everyone,

    I have a ProtocolHandler that is mostly used to stream remote tracks via HTTP. So, my ProtocolHandler subclasses HTTP.pm.

    In some cases, the remote tracks I'm streaming can be seeked into, by using the Range header.

    However, when StreamingController->jumpToTime is called, playingSong() returns an object that has a duration value of 0. This causes the jump to restart the song instead of seeking into it.
    I'm setting the duration in the getMetadata, but still getting 0 as duration of the Song object.

    Hacking in the _jumpToTime method, avoiding the early returns at different points, if I'm able to reach the section where seekdata is obtained, the Range header is set correctly and the seek happens successfully.

    Am I missing something that would allow me to create a Song object with a valid duration?

    Thanks,

  2. #2
    Babelfish's Best Boy mherger's Avatar
    Join Date
    Apr 2005
    Location
    Switzerland
    Posts
    19,782

    Trouble seeking into a remote track

    > Am I missing something that would allow me to create a Song object with
    > a valid duration?


    The duration should be set based on information received from the remote
    server or the file. I'm no expert in that field, never fully got it why
    some files would work, others not. But IIRC some file formats don't send
    that information in the header of the file, but rather towards the end
    of the file. Therefore those files can't be seeked, as we'd get the
    information too late (I think that's the case for m4a). Flac seeking has
    been a problem, too.

    Can you figure out some rule as to what files would work and which ones
    not? Like eg. the file format, or the remote server etc.?

    --

    Michael

  3. #3
    Senior Member pippin's Avatar
    Join Date
    Oct 2007
    Location
    Berlin
    Posts
    14,188
    I think with m4a it's not consistent but depends on the encoding, the metadata can be either at the front or end of the file.
    ---
    learn more about iPeng, the iPhone and iPad remote for the Squeezebox and
    Logitech UE Smart Radio as well as iPeng Party, the free Party-App,
    at penguinlovesmusic.com
    New: iPeng 9, the Universal App for iPhone, iPad and Apple Watch

  4. #4
    Senior Member
    Join Date
    Oct 2005
    Location
    Ireland
    Posts
    15,332
    How are you setting the duration in the getmetadata. ?
    Have you also implemented canSeek and getSeekData ?
    IIRC you may also have to set with "duration" of the song object (I think you can get Song object from the playing url)

  5. #5
    Junior Member
    Join Date
    Mar 2010
    Location
    Costa Rica
    Posts
    20
    Thanks to all for your input!

    Quote Originally Posted by mherger View Post
    Can you figure out some rule as to what files would work and which ones
    not? Like eg. the file format, or the remote server etc.?
    We actually proxy most of the services to delegate the complexity of multiple services away from the plugin. And we do get different formats, some with embedded info about the duration, some with external data, some with no data. We do sort around those.

    Quote Originally Posted by bpa View Post
    Have you also implemented canSeek and getSeekData ?
    We are implementing canSeek and getSeekData (actually, using HTTP.pm's methods, which work for us).

    Quote Originally Posted by bpa View Post
    How are you setting the duration in the getmetadata. ?
    ...
    IIRC you may also have to set with "duration" of the song object (I think you can get Song object from the playing url)
    This seems to be on the right track. We set the duration in the metadata, but not in the song object.
    I'm trying some things with the song object in my getMetadataFor method, I'll keep you posted on how that goes.

  6. #6
    Junior Member
    Join Date
    Nov 2014
    Posts
    7

    I need some help with the same thing...

    I am trying to play a HTTP stream. The HTTP server returns 206 (partial content) but specifies the range and total number of bytes.

    It is NOT from an Icecast server, but a standard HTTP server (though I could get the right headers added if I knew what they needed to say).

    Right now, LMS plays the first segment the server returns... then plays that again... then stops.

    The server sees a request which it responds to with a 206... then the server gets the request again (not a range request, but a simple GET request for the entire data file (300 MB) which it will not return in its entirety.

    I was hoping LMS might request the segments as it played them using range requests. I thought I'd read in the forums that this was possible.

    I'm assuming I'm not indicating the right information in my protocol handler for this to happen.

    Can anyone look at my code below and suggest what I should add/alter/remove to get the stream to play from beginning to end?

    I have a protocol handler with the folowing:

    use strict;
    use base qw(Slim::Player::Protocols::HTTP);
    use Slim::Utils::Log;
    use Slim::Utils::Errno;
    use Scalar::Util qw(blessed);

    Slim::Player::ProtocolHandlers->registerHandler('myplugintest', __PACKAGE__);

    sub new {
    my $class = shift;
    my $args = shift;

    my $client = $args->{'client'};
    my $song = $args->{'song'};

    my $streamUrl = 'http://192.168.1.5:9720/test?source=stream.aac';
    #Hardcode path to test stream

    my $sock = $class->SUPER::new( {
    'url' => $streamUrl,
    'song' => $song,
    'client' => $client,
    } ) || return;

    ${*$sock}{'contentType'} = 'audio/mpeg';

    return $sock;
    }

    sub scanUrl {
    my ($class, $url, $args) = @_;
    $args->{cb}->( $args->{'song'}->currentTrack() );
    }

    sub getFormatForURL () { 'mp3' }
    sub canSeek { 0 }
    sub isRepeatingStream { 0 }
    sub isRemote { 1 }
    sub canDirectStreamSong {
    my ( $class, $client, $song ) = @_;
    return 0;
    }

    sub getMetadataFor {
    my ( $class, $client, $url, $forceCurrent ) = @_;

    my $song = $forceCurrent ? $client->streamingSong() : $client->playingSong();
    return {} unless $song;

    $song->duration(9830); # Hardcode the duration of the test stream

    return {
    'title' => 'Http Range Stream Test',
    'artist' => 'Whoever',
    'album' => 'Whatever',
    'bitrate' => '256',
    'type' => 'MP3',
    }
    }
    Last edited by littla; 2017-01-24 at 08:50.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •