AddFromURL does not support ogg streams

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
39 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: AddFromURL does not support ogg streams

trustfm
Hello ! Thanks for your efforts
From the latest zip i get
CURL + MP3 WORKS
CURL + OPUS no work
CURL + AAC works
CURL+ OGG no work

i have
/usr/lib/x86_64-linux-gnu/libcurl.so.4
Reply | Threaded
Open this post in threaded view
|

Re: AddFromURL does not support ogg streams

fredvs
Administrator
Ho, thanks to test it.
I see that OPUS is not working with curl, is it working if you use uos_httpgetthread.pas (the fphttp version)?
Reply | Threaded
Open this post in threaded view
|

Re: AddFromURL does not support ogg streams

trustfm
in that version i havent tested yet but in the older one worked with volume 100% but once the volume was lowered it played intermittently ....
Reply | Threaded
Open this post in threaded view
|

Re: AddFromURL does not support ogg streams

fredvs
Administrator
In reply to this post by trustfm
I dont have a demo ready to test OPUS files (I dont have Lazarus installed to test the Lazarus simple player demo).

But, in your uos_define.inc, is it enabled:

{$DEFINE opus} // uncomment to enable opus (opus audio file)

Reply | Threaded
Open this post in threaded view
|

Re: AddFromURL does not support ogg streams

trustfm
ok i get (obvious error)
uos.pas(6844,3) Error: Duplicate identifier "s"

  {$IF DEFINED (opus)}
  s: UTF8String;
  OpusTag: POpusTags;
  {$endif}
 
  {$IF DEFINED (vorbis)}
  Info: PVorbis_Info;
  VorbisTag: PVorbis_Comment;
  timeout, oggStart: integer;
  {$endif}
 
  {$IF (DEFINED (opus)) or (DEFINED (vorbis))}
  s: UTF8String;
  LComment: PPAnsiChar;
  LcommentLength: PInteger;
  j: Integer;
  {$endif}


fixed that plays with fphttpclient but with the bug before on volume lower than 100%
now i will try with curl
Reply | Threaded
Open this post in threaded view
|

Re: AddFromURL does not support ogg streams

fredvs
Administrator
In reply to this post by trustfm
Hum, ok, I need to rejump in OPUS stream.
But the code of Xiph.org (vorbis, ogg, opus,...) is not easy to understand, I remember that making OPUS files + websteam was not easy for uos.
Reply | Threaded
Open this post in threaded view
|

Re: AddFromURL does not support ogg streams

fredvs
Administrator
In reply to this post by trustfm
Ha you see, long time ago that I tested OPUS.  In fact I was very excited by that new audio format (yes, time goes on) but the passion is gone, nobody use it and finally no lot of advantage vs mp3 or aac.
Reply | Threaded
Open this post in threaded view
|

Re: AddFromURL does not support ogg streams

trustfm
This post was updated on .
In reply to this post by fredvs
Ok i have good news !
 
CURL + MP3 WORKS
CURL + OPUS WORKS with the volume 100% (lower plays intermittently)
CURL + AAC works
CURL+ OGG no work

Curl works better than fphttpclient in the opus example once i close the program freezes with curl no

************************
My goal was to hop between MP3-OPUS-AAC-OGG without the user selecting the format

I made a thread like this

  Synchronize(@Form1.ListenAudioFromURL);

  while uos_GetStatus(PlayerIndexAudioStreamer)<>-1 do begin //StreamingType=stDirectStreamMP3  uos_GetStatus(PlayerIndexAudioStreamer)<>-1
      Synchronize(@UpdateForm);

      if Form1.IsStoppedByUser then begin
        break;
      end;
      sleep(100);
  end;
  Synchronize(@UpdateForm2);
  uos_Stop(PlayerIndexAudioStreamer);

  if not Form1.IsStoppedByUser then begin

    Synchronize(@UpdateForm2);

    //ShowMessage('NOt stopped by the user !!!');

      Form1.StreamingType:=stDirectStreamAAC;

      Synchronize(@Form1.ListenAudioFromURL);

      while uos_GetStatus(PlayerIndexAudioStreamer)<>-1 do begin //StreamingType=stDirectStreamMP3

          Synchronize(@UpdateForm2);

          if Form1.IsStoppedByUser then begin
            break;
          end;
          //Application.ProcessMessages;
          sleep(100);
      end;        


************************

But using the fphttpclient even if the uos_GetStatus(PlayerIndexAudioStreamer) was -1 the  fphttpclient  thread was running and mine thread  called the next ListenAudioFromURL ....        
Reply | Threaded
Open this post in threaded view
|

Re: AddFromURL does not support ogg streams

fredvs
Administrator
Yep great news.
OK, so for OPUS some tweaking needed but not a mountain.

For OGG streaming, I need a break tonight, I am blocked in the readURL mehods for OGG streams.

By the way, if you are on Linux adding -duos_debug parameter for compilation gives debug infos when running the demo via a terminal.
Reply | Threaded
Open this post in threaded view
|

Re: AddFromURL does not support ogg streams

trustfm
ok i will test it tomorrow too ...
Opus is not a huge problem .
Thank you
Reply | Threaded
Open this post in threaded view
|

Re: AddFromURL does not support ogg streams

fredvs
Administrator
OK, many thanks for testing.

Huh, what radio-web using opus streams can I test?
Reply | Threaded
Open this post in threaded view
|

Re: AddFromURL does not support ogg streams

fredvs
Administrator
In reply to this post by trustfm
For detecting what kind of format is the url, before to create the player and his addfromurl(), you may use a pre-check, like this:

program detect_stream_format.
uses
  fphttpclient, sysutils;

function GetStreamContentType(const URL: string): string;
var
  HTTPClient: TFPHTTPClient;
begin
  Result := '';
  HTTPClient := TFPHTTPClient.Create(nil);
  try
    HTTPClient.AllowRedirect := True; // Handle redirects
    HTTPClient.Head(URL); // Perform a HEAD request
    Result := HTTPClient.ResponseHeaders.Values['Content-Type'];
  finally
    HTTPClient.Free;
  end;
end;

procedure DetectStreamFormat(const URL: string);
var
  ContentType: string;
begin
  ContentType := LowerCase(GetStreamContentType(URL));
  Writeln('Content-Type: ', ContentType);

  if Pos('audio/mpeg', ContentType) > 0 then
    Writeln('Detected format: MP3')
  else if Pos('audio/ogg', ContentType) > 0 then
    Writeln('Detected format: Ogg (could be Vorbis or Opus)')
  else if Pos('audio/aac', ContentType) > 0 then
    Writeln('Detected format: AAC')
  else if Pos('application/ogg', ContentType) > 0 then
    Writeln('Detected format: Ogg (could be Vorbis or Opus)')
  else
    Writeln('Unknown format, further inspection needed');
end;

begin
  DetectStreamFormat('http://example.com/stream');
end.

I will asap add a uos method to get the format before player create.
Reply | Threaded
Open this post in threaded view
|

Re: AddFromURL does not support ogg streams

trustfm
Great !
Here is a list of all streams that i test
      EditURL.text := 'http://stream-uk1.radioparadise.com/mp3-128';
      //EditURL.text := 'http://s1.knixx.fm:5347/dein_webradio_vbr.opus';
      //EditURL.text := 'http://stream.freemusicradio.nl:8100/stream.aac';
      //EditURL.text := 'http://stream.punkrockers-radio.de:8000/prr.ogg';
      http://stream.dancewave.online:8080/dance.ogg
     
Reply | Threaded
Open this post in threaded view
|

Re: AddFromURL does not support ogg streams

fredvs
Administrator
OK, thanks.  Do you use a uos demo to test or do you test it with your own program?
If you use a uos demo, what demo?
Reply | Threaded
Open this post in threaded view
|

Re: AddFromURL does not support ogg streams

trustfm
This post was updated on .
here is my demo
https://trim.uk.to/ogg-radio-listenver2.zip

Has
*the part of your demo simplewebplayer (working except ogg)
*the part http://uos-forum.108.s1.nabble.com/file/n1309/uos_curl.zip
*the libvorbisfile library http://uos-forum.108.s1.nabble.com/file/n1310/libvorbisfile-64.zip
*****************
and the part The test zone that has
the download stream (working) + DownloadPlay(works only what downloaded)

It is a codetyphon project


*****************************************


PS : One important downside of the OPUS is the fact that works only at 48000 samplerate .
 I have tried to move from OGG to opus for the recording part but works at 48000 and my card has 44100 so plays accelerated the recording .

//modded to record opus
function Tuos_Player.AddIntoFile (Filenamepath: PChar; SampleRate: CDouble;
                                 Channels: cint32; SampleFormat: cint32; FramesCount: cint32;
                                 FileFormat: cint32): cint32;
// Add an Output into audio wav file with custom parameters
// FileName : filename of saved audio wav file
// SampleRate : default: -1 (44100)
// Channels : default: -1 (2:stereo) (0: no channels, 1:mono, 2:stereo, ...)
// SampleFormat : default: -1 (2:Int16) ( 1:Int32, 2:Int16)
// FramesCount : default: -1 (= 4096)
// FileFormat : default: -1 (wav) (0:wav, 1:pcm, 2:custom, 3:ogg, 4:opus);
//  result : Output Index in array  -1 = error
// example : OutputIndex1 := AddIntoFile (edit5.Text,-1,-1, 0, -1, -1);
var
  x: cint32;
  wChunkSize: cint32;
  wFileSize: cint32;
  IDwav: array[0..3] of char;
  Header: Tuos_WaveHeaderChunk;
  {$IF DEFINED (sndfile)}
  sfInfo: TSF_INFO;
  {$endif}

begin
  result := -1;
  x := 0;
  SetLength (StreamOut, Length (StreamOut) + 1);
  StreamOut[Length (StreamOut) - 1] := Tuos_OutStream.Create ();
  x := Length (StreamOut) - 1;
  StreamOut[x].Data.Enabled := false;
  StreamOut[x].FileBuffer.ERROR := 0;
  StreamOut[x].Data.Filename := filenamepath;
  if (FileFormat = -1) or (FileFormat = 0) then
    StreamOut[x].FileBuffer.FileFormat := 0
  else StreamOut[x].FileBuffer.FileFormat := FileFormat;

  FillChar (StreamOut[x].FileBuffer, sizeof (StreamOut[x].FileBuffer), 0);

  result := x;

  if (Channels = -1) then
    StreamOut[x].FileBuffer.wChannels := 2
  else
    StreamOut[x].FileBuffer.wChannels := Channels;

  StreamOut[x].Data.Channels := StreamOut[x].FileBuffer.wChannels;

  if FramesCount = -1 then  StreamOut[x].Data.Wantframes :=  65536 Div StreamOut[x].Data.Channels
  else
    StreamOut[x].Data.Wantframes := FramesCount;

  SetLength (StreamOut[x].Data.Buffer, StreamOut[x].Data.Wantframes*StreamOut[x].Data.Channels);

  if (SampleFormat = -1) or (SampleFormat = 2) then
    begin
      StreamOut[x].FileBuffer.wBitsPerSample := 16;
      StreamOut[x].Data.SampleFormat := 2;
    end;

  if (SampleFormat = 1) then
    begin
      StreamOut[x].FileBuffer.wBitsPerSample := 32;
      StreamOut[x].Data.SampleFormat := 1;
    end;

  if (SampleFormat = 0) then
    begin
      StreamOut[x].FileBuffer.wBitsPerSample := 32;
      StreamOut[x].Data.SampleFormat := 0;
    end;

  if SampleRate = -1 then
    StreamOut[x].FileBuffer.wSamplesPerSec := 44100
  else
    StreamOut[x].FileBuffer.wSamplesPerSec := roundmath (samplerate);

  StreamOut[x].Data.Samplerate := StreamOut[x].FileBuffer.wSamplesPerSec;
  StreamOut[x].LoopProc := Nil;

  if fileformat = 3 then
    begin
      // ogg file
  {$IF DEFINED (sndfile)}
      StreamOut[x].FileBuffer.FileFormat := 3;
      StreamOut[x].Data.TypePut := 6;
      sfInfo.format := SF_FORMAT_OGG Or SF_FORMAT_VORBIS;
      sfInfo.channels := StreamOut[x].Data.Channels;
      sfInfo.frames :=  streamOut[x].Data.Wantframes;
      SFinfo.samplerate := StreamOut[x].FileBuffer.wSamplesPerSec;
      SFinfo.seekable := 0;
      StreamOut[x].Data.Enabled := True;
      StreamOut[x].Data.HandleSt := sf_open (pchar (FileNamepath), SFM_WRITE, sfInfo);
  {$endif}
    end
  else if fileformat = 4 then begin  //by trustfm
    StreamOut[x].FileBuffer.FileFormat := 3;
    StreamOut[x].Data.TypePut := 6;
    sfInfo.format := SF_FORMAT_OGG or SF_FORMAT_OPUS; //SF_FORMAT_OGG Or SF_FORMAT_VORBIS;

    sfInfo.channels := StreamOut[x].Data.Channels;
    sfInfo.frames :=  streamOut[x].Data.Wantframes;
    sfinfo.samplerate := 48000;// StreamOut[x].FileBuffer.wSamplesPerSec; //48000;  OPUS WORKS AT 48000 ONLY :(
    //SFinfo.samplerate := StreamOut[x].FileBuffer.wSamplesPerSec;
    SFinfo.seekable := 0;
    StreamOut[x].Data.Enabled := True;
    StreamOut[x].Data.HandleSt := sf_open (pchar (FileNamepath), SFM_WRITE, sfInfo);
  end
  else
    begin
      // wav file
      StreamOut[x].FileBuffer.Data := TFileStream.Create (filenamepath,fmCreate);
      StreamOut[x].FileBuffer.Data.Seek (0, soFromBeginning);
      StreamOut[x].Data.TypePut := 0;
      IDwav := 'RIFF';
      StreamOut[x].FileBuffer.Data.WriteBuffer (IDwav, 4);
      wFileSize := 0;
      StreamOut[x].FileBuffer.Data.WriteBuffer (wFileSize, 4);
      IDwav := 'WAVE';
      StreamOut[x].FileBuffer.Data.WriteBuffer (IDwav, 4);
      IDwav := 'fmt ';
      StreamOut[x].FileBuffer.Data.WriteBuffer (IDwav, 4);
      wChunkSize := SizeOf (Header);
      StreamOut[x].FileBuffer.Data.WriteBuffer (wChunkSize, 4);

      case SampleFormat of
        0:   Header.wFormatTag      := 3;
        else Header.wFormatTag      := 1;
      end;

      //Header.wFormatTag      := 1;
      Header.wChannels       := StreamOut[x].FileBuffer.wChannels;
      Header.wSamplesPerSec  := StreamOut[x].FileBuffer.wSamplesPerSec;
      Header.wBitsPerSample  := StreamOut[x].FileBuffer.wBitsPerSample;
      Header.wBlockAlign     := StreamOut[x].FileBuffer.wChannels * Header.wBitsPerSample Div 8;
      Header.wAvgBytesPerSec := StreamOut[x].FileBuffer.wSamplesPerSec * Header.wBlockAlign;
      Header.wcbSize         := 0;

      StreamOut[x].FileBuffer.Data.WriteBuffer (Header, SizeOf (Header));
      IDwav := 'data';
      StreamOut[x].FileBuffer.Data.WriteBuffer (IDwav, 4);
      wChunkSize := 0;
      StreamOut[x].FileBuffer.Data.WriteBuffer (wChunkSize, 4);
      StreamOut[x].Data.Enabled := True;

    end;
end;

*******************************************************
In summary my only working path right now for my project is the following

[GENERIC PLAYER Like SimplePlayer Example]->
[RECORDER OGG like simplerecorder]->
[BROADCASTER OGG discussed and working in other thread http://uos-forum.108.s1.nabble.com/Installing-IceCast-audio-web-server-td184.html]->
[OGG LISTENER not working (like simple webplayer) OGG DOWNLOADER WORKING]  
Reply | Threaded
Open this post in threaded view
|

Re: AddFromURL does not support ogg streams

trustfm
i have found that my download first listen after method has this problem
https://github.com/libsndfile/libsndfile/issues/421

Do we have progress with your streaming approach ?
Reply | Threaded
Open this post in threaded view
|

Re: AddFromURL does not support ogg streams

fredvs
Administrator
Hello.

It was already discussed there: https://github.com/libsndfile/libsndfile/pull/457

Dont know if there was progress for webstream.
Maybe you can take inspiration from uos_addFromMemory() stream and see how to adapt uos_addfromURL() and the readurl() method for reading OGG.

You can use the uos_addfromURL()/readurl() that I gave in uos.pas/uos_flat.pas of previous post zip-attachment and adapt it.

Sorry but I will be out of my computer this month.
Reply | Threaded
Open this post in threaded view
|

Re: AddFromURL does not support ogg streams

trustfm
Thank you !
No woories !
For reference here is my output from the debug

**********************************
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
before uosPlayers[PlayerIndex] <> nil
after uosPlayers[PlayerIndex] <> nil
Begin Vorbis test
URL: http://stream.punkrockers-radio.de:8000/prr.ogg
totsamples: 16384
PipeBufferSize: 131072
Seekable set to: False for AudioFormat: 3
Bytes available after wait: 12946
Timeout count: 9
PipeBufferSize = 131072
InPipe.Read = 131072
----------------------------------
BufferTMP content: 4F 67 67 53 00 02 00 00 00 00 00 00 00 00 BB 40 52 51 00 00 00 00 0C 90 6D CE 01 1E 01 76 6F 72 62 69 73 00 00 00 00 02 44 AC 00 00 00 EE 02 00 00 EE 02 00 00 EE 02 00 B8 01 4F 67 67 53 00 00 00 00 00 00 00 00 00 00 BB 40 52 51 01 00 00 00 A4 A9 57 43 10 AB FF FF FF FF FF FF FF FF FF FF FF FF FF FF 71 03 76 6F 72 62 69 73 34 00 00 00 58 69 70 68 2E 4F 72 67 20 6C 69 62 56 6F 72 62
OggS start position: 0
uos.pas: ov_open_callbacks succeeded, LibOpen = 5
StreamIn[x].Data.HandleSt url assigned
ov_info raw: channels = 0, rate = 2
OK open
VorbisTag.comments = 3
title=Don't Ever Say Again
artist=The Offenders
ENCODER=Liquidsoap/2.0.7 (Unix; OCaml 4.14.1)
End Tag Vorbis
ov_info failed or returned invalid data - forcing channels = 2, samplerate = 44100
Info^.channels = 2
Info^.rate = 44100
StreamIn[x].Data.Wantframes := totsamples
SetLength(StreamIn[x].Data.Buffer, StreamIn[x].Data.Wantframes);
End Vorbis
Channels: 2
SampleRate: 44100
Title: Don't Ever Say Again
Genre: »@RQ»@RQ±
AddFromURL Result forced to 0
AddFromURL final Result: 0
total end vorbis
ac StreamIn[x].Data.LibOpen = 5
Before result 0
error 0
StreamIn[x].Data.LibOpen 5
Before Length (StreamIn) 1
Before for x := 0 to high (StreamIn)
DSPin BeforeBufProc 1
DSPin BeforeBufProc 2
===> Before ov_read for Vorbis
Seekable: False
Begin Float32 output
here stops
Reply | Threaded
Open this post in threaded view
|

Re: AddFromURL does not support ogg streams

fredvs
Administrator
This post was updated on .
Hello.

The result is promising, connection to the url seems ok and get tag from the stream ok.
But it fails when trying to read using ov_read from uos_vorbisfile.pas, like I had.

Maybe try to use libsndfile to read the buffer instead of libvorbisfile, and so you will need to load the 2 libraries.
[EDIT] Or maybe forget all call to uos_vorbisfile in AddFromURL() and use call to libsndfile.
Take a look at AddFromMemoryStream() how it is done for libsndfile with sf_open_virtual() and adapt it for AddFromURL().  And to read it, use sf_read vs ov_read.

Sorry I cannot help more before next month.
12