Поток MP3 . Чтение и Metadata (ЕSP32)

progersan
Offline
Зарегистрирован: 06.11.2020

Добрый день, как говорится, Коллеги! :) 

Я не один день мучился: гуглил и кодил. Но всегда начинаю сначала. Я программировал в очень разных средах до этого, "ардуинами" занялся недавно как решил попробовть ESP32. 

Помогите решить 2 задачи:
1. Чтение потока правильно. Не совсем понимаю какой вид переменной использовать верно будет для хранения считанного байта. Далее хочу его поместить в массив и т.о. сделать буфер. Само собой для последущего скармливания этого материала некому "плееру" для наслаждения моих ушей. Я бы начал с малого: прочитать байт, рассмотреть его и понять где начало "даты" и где она закончилась и началась "метадата", которая идет символьная...
2. Поиск в нем метаданных. Если коротко о теории, нашел такой текст: "...включите этот следующий заголовок! Icy-MetaData:1 Это сообщает серверу, что вы хотите метаданные. Теперь отправьте пару <CrLf>Хорошо, сервер ответит кучей заголовков, а затем начнет отправлять вам данные. В этих заголовках будет icy-metaint:8192 или аналогичный. Этот 8192 является метаинтервалом. Это важно и действительно единственное значение, которое вам нужно. Обычно это 8192, но не всегда, поэтому обязательно прочитайте это значение! В основном это означает, что вы получите 8192 байта данных MP3, а затем фрагмент мета, за которым следуют 8192 байта данных MP3, а затем фрагмент мета."  Взято отсюда   https://fooobar.com/questions/301373/pulling-track-info-from-an-audio-stream-using-php

В теории прям легко :) 

Итак, с чего я начал? Простое подключение через WiFiClient

  
const char * streamLink3 ="mp3.ffh.de"; 
  const char * streamPath3 ="/radioffh/hqlivestream.mp3";
  unsigned int streamPort3 =80;

  while(!client.connect(streamLink3, streamPort3)) 
  {
    Serial.println("!client.connect - RETRY");  
  }
 client.print(String("GET ") + streamPath3 + " HTTP/1.1\r\n" +
                "Host: " + streamLink3 + "\r\n" +    
                "Accept: */*\r\n"+              
                "Accept-Encoding: gzip, deflate, br\r\n"+
                "Connection: keep-alive\r\n\r\n" 
              );    
  Serial.println("connection is OK"); 

И вот в "лупе" у меня уже есть несколько вариантов но ни 1 из них не работает. 
Самое простое это побайтно прочитать , это уже азы и все так умеют.

Если сделать вот так, то я получаю некий байт. Он может быть символом, а может и не быть. Не знаю что с этой картиной делать. Нашел некую закономерность, но а дальше тупняк. 

uint8_t tmpbuff = client.read();

Увидел на просторах интернетиков небольшой цикл вроде как по поиску такого "мета" , но на Java. Немного округлил, оно взлетело на "ардуино". Да, когда интерпретировал код мне не понравилось, что в Java int брался для чтения данных. У меня с ним не работало правило while ((b = client.read()) != -1) и я переделал на uint8_t. Что-то стало крутится после этого. int metaDataOffset=16000 я взял из потока данного немецкого стрима "mp3.ffh.de" (что в коде выше). У "нашего радио" кажется этот параметр 8192. 

int metaDataOffset=16000; //8192; //TODO
    uint8_t b;
    int count = 0;
    int metaDataLength = 4080; // 4080 is the max length
    boolean inData = false;
    String metaData;
    int newStrCounter=0;
    // Stream position should be either at the beginning or right after headers
    while ((b = client.read()) != -1) {
      count++;

      // Length of the metadata
      if (count == metaDataOffset + 1) {
        metaDataLength = b * 16;
      }
      if (count > metaDataOffset + 1 && count < (metaDataOffset + metaDataLength)) {        
        inData = true;
      } else {        
        inData = false;       
      }         
      if (inData) {         
        if (b != 0) {           
          metaData += (char )b;    
          //Serial.println("[");
          newStrCounter++;
          if (newStrCounter>100)
          { newStrCounter=0;
          Serial.println(" ");
          }
          
          Serial.print( b);
          //Serial.println("]");     
        }       
      }         
      if (count > (metaDataOffset + metaDataLength)) 
      {
        Serial.println("break---");
        break;
      }
    }

Это про то как я узнал размер "фрейма"

В общем прошу помощи. Для начала бы просто в цикле читать данные, научится понимать этот блок и раскидывать в 2 кучи: метадата и дата (mp3)

 

Прошу помощи. Может кому-то вместе со мной будет интересно разобрать такой материал , а может кто-то уже решил таких задач десятки - поделитесь. Заранее всем спасибо!

 
mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Питоновец - да? Привык за слова не отвечать, а в си придется...

progersan
Offline
Зарегистрирован: 06.11.2020

mykaida пишет:

Питоновец - да? Привык за слова не отвечать, а в си придется...

не, с питоном никогда не знаком :) начинал я в C++, а дальше понесло в PHP и 1С, 

Вы бы по делу что-нибудь написали 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

progersan пишет:

не, с питоном никогда не знаком :) начинал я в C++, а дальше понесло в PHP и 1С, 

Вы бы по делу что-нибудь написали 

Вот как-то не верю после этого вопроса: "Не совсем понимаю какой вид переменной использовать верно будет для хранения считанного байта. "

progersan
Offline
Зарегистрирован: 06.11.2020

ну ладно вам! человек переработал. Уже голова кипит. А тут целый день 1С ковырял. Накладывает свой отпечаток. Я с потоками и байтами имею дело раз в год. По большим праздникам

sadman41
Offline
Зарегистрирован: 19.10.2016

Нет "в Ардуине" никаких потоков, в сущности. Массивы создаёшь байтовые и сохраняешь туда из регистров читанные байты. А потом интерпретируешь как текст или как raw-данные. Контроллеру все равно абсолютно.

progersan
Offline
Зарегистрирован: 06.11.2020

Update с фронтов. Метадату удалось увидеть, она все-таки существует!
Буду дальше думать над задачами.

https://prnt.sc/vesdrd

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

progersan пишет:

Update с фронтов. Метадату удалось увидеть, она все-таки существует!
Буду дальше думать над задачами.

https://prnt.sc/vesdrd

Это с какой-такой программы такие метах-данные? Я ее не видел и не целовал.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

даже я знакомое слово увидел  - LAME3.99.5  )))

progersan
Offline
Зарегистрирован: 06.11.2020

mykaida пишет:

progersan пишет:

Update с фронтов. Метадату удалось увидеть, она все-таки существует!
Буду дальше думать над задачами.

https://prnt.sc/vesdrd

Это с какой-такой программы такие метах-данные? Я ее не видел и не целовал.

да ну что вы. данные такие с любого MP3 потока получаются (возможно и AAC) , а программа - это монитор порта Arduino

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

progersan пишет:

да ну что вы. данные такие с любого MP3 потока получаются (возможно и AAC) , а программа - это монитор порта Arduino

Ой, подкололи :) А откуда берутся данные для монитора порта Вы догадываетесь? 

progersan
Offline
Зарегистрирован: 06.11.2020

мда... не ожидал такой "теплой" встречи. Думал, найду единомышленников. В итоге одни подколы и странные вопросы. 

В первом посте я описал задачу свою. Что я читаю и откуда. Даже ссылку на сайт дал. 
Одному "питон жмет", второй не поймет какая программа? Да вроде форум "ардуино", программа ведь так же называется. Никаких других программ не использую. Девайс только у меня ESP32. Но это я указал в названии топика.

Злые вы, уйду я от вас!

p.s. понимаю, что уровень моей "грамоты" не самый высокий. Но ведь для этого люди и общаются и задают вопросы. И форум кажется для этого и сделан. Иначе нахуа?

sadman41
Offline
Зарегистрирован: 19.10.2016

В жизни вообще нет единомышленников. Разве что в пивной, после второй кружки.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

progersan пишет:

мда... не ожидал такой "теплой" встречи. Думал, найду единомышленников. В итоге одни подколы и странные вопросы. 

Вы нарушили одно из основных правил сетевой этики: прежде, ем писать на форум, следует хотя бы 2-3 дня его почитать.

Цитата:

Но ведь для этого люди и общаются и задают вопросы. И форум кажется для этого и сделан. Иначе нахуа?

Вот-вот!

Если бы Вы придерживались правил сетевой этики, то знали бы:

- зачем нужен этот форум (совсем не для того, для чего Вы предполагаете),

- что указывать старожилам, для чего нужен форум - mauvais ton на данном форуме.