espressif / esp-adf

Espressif Audio Development Framework
Other
1.52k stars 669 forks source link

Get time position by byte position from decoder (AUD-4714) #1035

Closed masterxq closed 12 months ago

masterxq commented 1 year ago

Is your feature request related to a problem? Please describe.

I have implemented an audio player that supports seek and nice buffering and all that stuff.

I tried some combination, and got the result that i can get a byte position from a given second in currently decoded track:

size_t byte_pos = 0;
int size_of_byte_pos = sizeof(byte_pos);
uint64_t time_pos_in = *(int *)msg.data;
decoder_get_pos(&decoder, &time_pos_in, sizeof(time_pos_in), &byte_pos, &size_of_byte_pos);

This provides time->byte pos. How to get byte->time pos?

Currently, I do this by binary search ^^ This feels so bad, and can breaks on edge cases... So it could be nice to have this available or know how to do :)

The Additional question is:

If somebody has an array of decoder, how to ask the currently selected/working decoder? How can the request be routed? Is there an API that provides this?

Describe the solution you'd like

I would love to have an interface like this:

//Returns the time in seconds or something <0 if it fails (element cant provide this api call, invalid byte pos, decoder error...)

int32_t audio_element_get_seconds_by_byteoffset(audio_element_handle_t el, size_t byte_pos);
int32_t audio_element_get_seconds_from_current_position(audio_element_handle_t el);

//Or maybe this style:
esp_err_t audio_element_get_seconds_by_byteoffset(audio_element_handle_t el, size_t byte_pos, int *seconds);

Describe alternatives you've considered

It is possible to use binary search... but not good

Additional context

It's hard to show the current track position without this information...

TempoTian commented 1 year ago

Seek API often have two forms 1: byte seek 2: time seek If player support byte seek, can draw progress bar in percentage form if support time seek, get total duration and current time is enough, player only need to provide time to position conversion so that can seek to required byte position.

The working decode type can get from audio_element_getinfo/codec_fmt, to select the decode type need some basic knowledge of container, you can get audio type from container by parse file header.

esp_audio get current time position from output element, output element only support pcm audio type, so it is easy to get the time according input data size, samplerate and sample size. Element is common part, no need provide get_seconds API, Player can calculate by itself.

masterxq commented 1 year ago

Thanks for you reply @TempoTian!

I know It's completely off-topic, but it would also give answer to all my questions. Ofc I can open another ticket about it, but would it be possible to make an example which supports seeking without esp_audio_lib (priority on time seek as it is often what the user want). It would also help others with same kind questions. If the answer is yes here, I would suggest not spending more time in answering my questions, just write yes and "close with comment" and I will open a new ticket with a feature request about the example. If your progress requires it I can close this too if you write yes :)

Otherwise, I have some questions: :)

This is really helpfully and answering the other part of the question:

The working decode type can get from audio_element_getinfo/codec_fmt, to select the decode type need some basic knowledge of container, you can get audio type from container by parse file header.

If player support byte seek, can draw progress bar in percentage form if support time seek, get total duration and current time is enough, player only need to provide time to position conversion so that can seek to required byte position.

Yes ofc you are right, but how to get the current time position? I could not find a working API call, at least not from the MP3 player which I tested most.

Maybe you are answering my question here, and did just not try to get this from the output element:

esp_audio get current time position from output element, output element only support pcm audio type, so it is easy to get the time according input data size, samplerate and sample size. Element is common part, no need provide get_seconds API, Player can calculate by itself.

Can the output element track the time position per track? How does it work? And specially if a previous seek was called? Sorry for asking, but I think the answer could help me to understand how it should be used.

Thanks for your time! I would love to be able to discard a lot of custom code :)

TempoTian commented 1 year ago

Sorry, It's technical details, I can not answer you for it. Basicly time position can be got from PCM samples received, PCM sample can be calculated from byte position, you can try to implement through this clue.

jason-mao commented 12 months ago

This topic has become inactive so I'm going to close the issue. Please reopen this if you have any questions or need any further assistance.