Author Topic: Streaming encrypted mp3  (Read 237 times)

Jerzy Piechowiak

  • Posts: 3
Streaming encrypted mp3
« on: 23 Dec '22 - 15:54 »
Hi,

we've been using BASS player for years with approach where we first download the file, and then play it with BASS.
Now we're trying streaming approach (our CDN can work with such scenario).

I've tried to BASS_StreamCreateURL method with DOWNLOADPROC and BASS_ChannelGetData. But during stream creation I'm receiving error BASS_ERROR_FILEFORM. It's probably because file is encrypted on our CDN site. It's any workaround for such issue?
It's even possible to download some chunks, decrypt them in DOWNLOADPROC using BASS_ChannelGetData and play it after all?
 
Code: [Select]
_channelHandle = Bass.BASS_StreamCreateURL(url,
    0,
    BASSFlag.BASS_STREAM_DECODE,
    _myDownloadProc,
    IntPtr.Zero);

Ian @ un4seen

  • Administrator
  • Posts: 25460
Re: Streaming encrypted mp3
« Reply #1 on: 23 Dec '22 - 18:03 »
Implementing decryption in a DOWNLOADPROC callback unfortunately won't work because the initially downloaded data is used for decoder initialization before the DOWNLOADPROC sees it (the DOWNLOADPROC only sees the data after successful decoder initialization). You would instead need to download the data yourself and use BASS_StreamCreateFileUser (with system=STREAMFILE_BUFFER) to play it, which allows you to decrypt the data before giving it to BASS via a FILEREADPROC callback. Note you don't need to pre-download the entire file in doing that; your FILEREADPROC function can fetch data as needed from a connection and decrypt it before returning it.

Jerzy Piechowiak

  • Posts: 3
Re: Streaming encrypted mp3
« Reply #2 on: 24 Dec '22 - 10:50 »
Ok. Tkanks. I’ll try this after Christmas.

Jerzy Piechowiak

  • Posts: 3
Re: Streaming encrypted mp3
« Reply #3 on: 29 Dec '22 - 16:00 »
Ok I was able to make this partially working:
Code: [Select]
var fileProc = new BASS_FILEPROCS(
    OnCloseStream,
    OnGetStreamLength,
    OnReadStream,
    OnSeekStream);

var channel = Bass.BASS_StreamCreateFileUser(BASSStreamSystem.STREAMFILE_BUFFER,
    BASSFlag.BASS_STREAM_DECODE,
    fileProc,
    IntPtr.Zero);

I've got a Stream which I read inside OnReadStream method, but it looks like that BASS is trying to read/stream the whole file at once - not only closest chunks. Is there any solution to keep only small buffer?
I've got also some issues with seeking, but I'll try to resolve this later.

Ian @ un4seen

  • Administrator
  • Posts: 25460
Re: Streaming encrypted mp3
« Reply #4 on: 29 Dec '22 - 17:16 »
The STREAMFILE_BUFFER system is the same as used by BASS_StreamCreateURL, and it will default to reading the entire file to memory as quickly as possible. You can use the BASS_STREAM_BLOCK flag to make it only keep a small amount (determined by BASS_CONFIG_NET_BUFFER) in memory at a time instead, and it will then only read more after previous data has been used/decoded, ie. new data replaces old data in memory. Note that because the data isn't retained, seeking via BASS_ChannelSetPosition isn't possible when the BASS_STREAM_BLOCK flag is used.

If you need to be able to seek without buffering then you could also try the STREAMFILE_NOBUFFER system, which is what's used by BASS_StreamCreateFile. Note you will need to implement the seeking yourself then in your FILESEEKPROC function, eg. perhaps reconnect to the server with a range request.