Comments (16)
@ioctlLR Right, well I can fix that (since I do know the total duration). That fixes the fetching the entire stream part.
The next issue is that seeking to an arbitrary position, causes ALL chunks leading up to that position to be fetched. So if a user seeks to for example 80%, almost the entire track has to be fetched, instead of doing some kind of bisection to find the correct page.
This does not occur in the UWP MediaPlayer, but it has its own issues so I can't really use that one.
from nvorbis.
Yeah... So when I designed the newest Ogg reader I built it to cache page header locations (and granules) to make seeking faster, assuming anything streamed wouldn't be seek-able anyway (there's a different IPacketProvider implementation for that). I don't think I ever expected a scenario where a streamed datasource would need to be seek-able.
Feel free to fork and modify the Ogg/PageReader & Ogg/PacketProvider types (or write your own) to support your specific scenario (I'll take a PR if you're interested!). That said, I think you're better off actually implementing your own IPacketProvider that understands "seeking" the source datastream. I'm pretty sure there's enough in the existing code it shouldn't be overly difficult.
from nvorbis.
Thanks! I’ll be sure to take a look and try and get it working for my use case. I agree it’s a very specific use case and most people just use a file system source. Thanks for your help
from nvorbis.
I was actually able to kinda fix this by removing some TotalLength checks in the setter of the Position.
Still, seeking to the end of a stream, causes the seeking to find the correct page in a sequential manner, rather than; let's say bisection.
Is there any way we can resolve this issue?
Thanks!
from nvorbis.
Can you share how you are using NVorbis for this? A minimal repro project would be great. Thanks!
from nvorbis.
Can you share how you are using NVorbis for this? A minimal repro project would be great. Thanks!
Thanks for your reply.
Basically what I’m doing is creating a custom System.IO stream, this stream fetches encrypted audio chunks from a url using a HttpClient and decrypts them using a very custom algorithm.
It’s getting kinda late here so I’ll try to make a reproducible app tomorrow.
from nvorbis.
This might be not be 100% related to this but your getting encrypted audio chunks, could i aske why you used a HttpClient and not a WebSocket if your streaming data it will be much more efficient, and might help a little with your re-downloading but i would agree that your better trying to get a bisect working.
Would love to see a repro app that may be able to help with that, as i have some experience in streaming tech but in the mean time could i confirm your chunks are around the "Ogg page"? as that's the way this should complete https://en.wikipedia.org/wiki/Ogg_page (you may know this im also putting it here for future references)
from nvorbis.
@barkermn01 well I have no control over the architecture, it’s a third party music streaming service. They host their audiofiles on a cdn which are encrypted using an algorithm. I will try to get a reproducible sample but ive been kinda busy with work. I’ll try to get one today
from nvorbis.
@barkermn01 @ioctlLR I've extracted the core components from my code (its literally the same code), but i've replaced the audio fetching with a FileStream that has a delay of 200ms for every chunk fetch.
https://github.com/christosk92/NVorbis_ReproSample
from nvorbis.
Thanks i will have a look as soon as i can, i know the busy with work thing myself :D
from nvorbis.
@christosk92 OK, the problem you're encountering is due to this line. Instead of asking NVorbis for that information, download the metadata for the audio stream and use the value from there.
There are only two ways to get the duration of an Ogg Vorbis audio stream: Read the granulePos of the last page in the stream (which in your case implies downloading the entire stream), OR get the duration from an external source. As far as I know there are no other options.
from nvorbis.
Awesome! And if you do happen to create a PR I'll be happy to work on it with you. Until then I'm going to close this item.
from nvorbis.
Short update:
I've managed to modify the code to fetch the latest page in the stream, and then calculating it granulepos to calculate the total time without fetching the whole stream.
It's my first time doing audio processing etc, but from what I've read online, I did the following:
- Seek to the end of the stream, MINUS one OGG page.
- Seek forward byte by byte until we find the OggS header AND until end of stream.
- Since one vorbis page might be smaller than the max size, seeking until the end of the stream allows us to find even the smallest pages.
- Use existing functions to add the page to the collection, which updates the maxgranulepos.
Next I'll try to implement bisection search (https://wiki.xiph.org/GranulePosAndSeeking)
from nvorbis.
@christosk92
your point 2 should not be needed If you have jumped to the last page of the stream, the first set of 4 bytes so bytes 0 to 3 (inclusive) should be the "OggS" 4F676753
Capture it's required to be there as part of the Ogg Spec.
After that you can seek to 24 bytes (seek forward by 21 from the end of the last read) read the next 4 bytes that will be the number of page segments then minus 1 from that then times it by 255 (the largest size a segment can be and will be unless it's the last) lets call this offset for ease, and finally seek forward by offset, your now at the last page and at the last segment seek forward until end to read end of page.
from nvorbis.
Well I know this might sound stupid but I just went ahead and made a whole new decoder (new project) since it was really hard for me to modify the existing code.
I ported symphonia(https://github.com/pdeljanov/Symphonia) from rust into c# and it works well.
If anyone's interested, i'll be looking to publish it to github once it's ready,
from nvorbis.
https://github.com/christosk92/WaveeVorbis
from nvorbis.
Related Issues (20)
- Need Unit Tests
- Weird issue ? HOT 10
- Playback timing issue with some ogg files HOT 5
- Exception when reading certain ogg files. HOT 6
- "Ran out of packets?!" when seeking HOT 14
- Granule Position was -1 but page does not have exactly 1 continued packet.
- "Could not read pre-roll packet!" exception when seeking HOT 1
- IndexOutOfRangeException in PacketProvider.CreatePacket while seeking HOT 5
- rollForward results in negative value on seeking, resulting in negative _prevPacketStart HOT 2
- ForwardOnlyPageReader exception on last page
- Documentation is ambiguous HOT 1
- Build on .NET 6 HOT 1
- Dead loop in StreamDecoder.Read() HOT 4
- VorbisReader class SamplePosition issue
- Please document that vorbis.SamplePosition/vorbis.TotalSamples are in Frames not samples HOT 2
- Seeking fails with "Could not read pre-roll packet"
- SamplePosition consistantly fails if you seek near the end of a file
- Dead loop in StreamDecoder.Read()
- Need lots more tests HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from nvorbis.