mirror of
https://github.com/sweidac/kidsbox.git
synced 2026-10-28 06:52:57 +01:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
648bbe53e6 | ||
|
|
e104256985 |
No files matched your search
@@ -12,12 +12,12 @@ AudioPlayer::AudioPlayer() {
|
|||||||
esp_audio_vol_set(playerHandle, 50);
|
esp_audio_vol_set(playerHandle, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioPlayer::play(std::string uri) {
|
void AudioPlayer::play(std::string uri, int position = 0) {
|
||||||
if (isLastUri(uri)) {
|
if (isLastUri(uri)) {
|
||||||
esp_player_music_resume();
|
esp_player_music_resume();
|
||||||
} else {
|
} else {
|
||||||
esp_player_music_stop();
|
esp_player_music_stop();
|
||||||
esp_player_sdcard_music_play(uri.c_str(), 0);
|
esp_player_sdcard_music_play(uri.c_str(), position);
|
||||||
lastUri = std::string(uri);
|
lastUri = std::string(uri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,3 +29,11 @@ void AudioPlayer::pause() {
|
|||||||
bool AudioPlayer::isLastUri(std::string uri) {
|
bool AudioPlayer::isLastUri(std::string uri) {
|
||||||
return lastUri == uri;
|
return lastUri == uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AudioPlayer::getPosition() {
|
||||||
|
int position;
|
||||||
|
|
||||||
|
esp_player_pos_get(&position);
|
||||||
|
|
||||||
|
return position;
|
||||||
|
}
|
||||||
@@ -8,8 +8,10 @@ class AudioPlayer {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
AudioPlayer();
|
AudioPlayer();
|
||||||
void play(std::string uri);
|
|
||||||
|
void play(std::string uri, int position);
|
||||||
void pause();
|
void pause();
|
||||||
|
int getPosition();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isLastUri(std::string uri);
|
bool isLastUri(std::string uri);
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
idf_component_register(SRCS "Networking.cpp" "main.cpp" "WebInterface.cpp" "RFIDInterface.cpp" "audio_setup.c" "AudioPlayer.cpp" "TagPlayerControl.cpp"
|
idf_component_register(SRCS "Networking.cpp" "main.cpp" "WebInterface.cpp" "RFIDInterface.cpp" "audio_setup.c" "AudioPlayer.cpp" "TagPlayerControl.cpp" "Tag.cpp"
|
||||||
INCLUDE_DIRS ".")
|
INCLUDE_DIRS ".")
|
||||||
@@ -0,0 +1,199 @@
|
|||||||
|
#include "Tag.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <cJSON.h>
|
||||||
|
|
||||||
|
#define BASE_PATH "/sdcard/internal/";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {
|
||||||
|
* tagId : "xa5_x1f_x13_xaa_x00",
|
||||||
|
* playlist : [
|
||||||
|
* "file://sdcard/music_intro.mp3",
|
||||||
|
* "file://sdcard/audiobook_chapter1.mp3",
|
||||||
|
* "file://sdcard/audiobook_chapter2.mp3"
|
||||||
|
* ],
|
||||||
|
* currentIndex : 0,
|
||||||
|
* currentPosition : 1234 // the position as returned by the player. can be frames, can be ms or anything
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
Tag::Tag() {}
|
||||||
|
|
||||||
|
Tag::Tag(char* tagId): Tag(std::string(tagId)) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Tag::Tag(std::string tagId): tagId(tagId) {
|
||||||
|
this->playlist = std::vector<std::string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tag::setCurrentPosition(uint32_t fileIndex, uint32_t position) {
|
||||||
|
this->currentFileIndex = fileIndex;
|
||||||
|
this->currentFilePosition = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Tag::getCurrentPosition() {
|
||||||
|
return this->currentFilePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Tag::getNextLink() {
|
||||||
|
return this->playlist.at(this->currentFileIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Tag::isLinked() {
|
||||||
|
return ! this->playlist.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tag::read() {
|
||||||
|
std::string contents;
|
||||||
|
|
||||||
|
try {
|
||||||
|
contents = readFileContents();
|
||||||
|
} catch (std::invalid_argument& e){
|
||||||
|
std::cout << "Execption while reading tag-file: " << e.what() << "\n";
|
||||||
|
|
||||||
|
write();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON* data = cJSON_Parse(contents.c_str());
|
||||||
|
|
||||||
|
char* tagId = cJSON_GetObjectItem(data, "tagId")->valuestring;
|
||||||
|
|
||||||
|
int currentIndex = cJSON_GetObjectItem(data, "currentIndex")->valueint;
|
||||||
|
|
||||||
|
if (currentIndex < 0) {
|
||||||
|
std::cout << "Bad file index, must be >= 0, was: " << currentIndex << "\n";
|
||||||
|
currentIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->currentFileIndex = currentIndex;
|
||||||
|
|
||||||
|
int currentFilePosition = cJSON_GetObjectItem(data, "currentPosition")->valueint;
|
||||||
|
|
||||||
|
if (currentFilePosition < 0) {
|
||||||
|
std::cout << "Bad file position, must be >= 0, was: " << currentFilePosition << "\n";
|
||||||
|
currentFilePosition = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->currentFilePosition = 0;
|
||||||
|
|
||||||
|
cJSON* playlist = cJSON_GetObjectItem(data, "playlist");
|
||||||
|
|
||||||
|
if (playlist) {
|
||||||
|
int playlistLength = cJSON_GetArraySize(playlist);
|
||||||
|
|
||||||
|
for (int i = 0; i < playlistLength; i++) {
|
||||||
|
cJSON* item = cJSON_GetArrayItem(playlist, i);
|
||||||
|
|
||||||
|
// each item is just an URL
|
||||||
|
this->playlist.push_back(std::string(item->valuestring));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_Delete(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tag::write() {
|
||||||
|
std::string contents = createFileContents();
|
||||||
|
|
||||||
|
std::cout << contents << std::endl;
|
||||||
|
|
||||||
|
std::string filePath = getFilePath();
|
||||||
|
|
||||||
|
std::ofstream file(filePath);
|
||||||
|
|
||||||
|
if (! file.is_open()) {
|
||||||
|
std::cout << "Error opening file for tag " << tagId << " before writing";
|
||||||
|
|
||||||
|
char* errorName;
|
||||||
|
|
||||||
|
switch (errno) {
|
||||||
|
case EACCES:
|
||||||
|
errorName = "EACCESS";
|
||||||
|
break;
|
||||||
|
case ENOENT:
|
||||||
|
errorName = "ENOENT";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errorName = "not parsed";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << errorName << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
file << contents << std::endl;
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Tag::createFileContents() {
|
||||||
|
cJSON* root = cJSON_CreateObject();
|
||||||
|
cJSON* playlist;
|
||||||
|
|
||||||
|
cJSON_AddStringToObject(root, "tagId", this->tagId.c_str());
|
||||||
|
cJSON_AddNumberToObject(root, "currentIndex", this->currentFileIndex);
|
||||||
|
cJSON_AddNumberToObject(root, "currentPosition", this->currentFilePosition);
|
||||||
|
playlist = cJSON_AddArrayToObject(root, "playlist");
|
||||||
|
|
||||||
|
for (auto& link: this->playlist) {
|
||||||
|
cJSON_AddItemToArray(playlist, cJSON_CreateString(link.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
char* json = cJSON_Print(root);
|
||||||
|
cJSON_Delete(root); // playlist is also free'd
|
||||||
|
|
||||||
|
std::cout << json << std::endl;
|
||||||
|
|
||||||
|
return std::string(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Tag::readFileContents() {
|
||||||
|
std::string filePath = getFilePath();
|
||||||
|
|
||||||
|
std::fstream file(filePath);
|
||||||
|
|
||||||
|
if (! file) {
|
||||||
|
std::cout << "Error opening file for tag " << tagId;
|
||||||
|
|
||||||
|
char* errorName;
|
||||||
|
|
||||||
|
switch (errno) {
|
||||||
|
case EACCES:
|
||||||
|
errorName = "EACCESS";
|
||||||
|
break;
|
||||||
|
case ENOENT:
|
||||||
|
errorName = "ENOENT";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errorName = "not parsed";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << errorName << "\n";
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
throw std::invalid_argument(errorName);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
std::string content;
|
||||||
|
|
||||||
|
while(getline(file, line)) {
|
||||||
|
content.append(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Tag::getFilePath() {
|
||||||
|
std::string filePath = BASE_PATH;
|
||||||
|
filePath.append(tagId);
|
||||||
|
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class Tag {
|
||||||
|
private:
|
||||||
|
std::string tagId{""};
|
||||||
|
std::vector<std::string> playlist;
|
||||||
|
uint32_t currentFileIndex{0};
|
||||||
|
uint32_t currentFilePosition{0};
|
||||||
|
|
||||||
|
public:
|
||||||
|
Tag();
|
||||||
|
Tag(std::string tagId);
|
||||||
|
Tag(char* tagId);
|
||||||
|
void read();
|
||||||
|
void write();
|
||||||
|
bool isLinked();
|
||||||
|
std::string getNextLink();
|
||||||
|
void setCurrentPosition(uint32_t fileIndex, uint32_t position);
|
||||||
|
int getCurrentPosition();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string createFileContents();
|
||||||
|
std::string readFileContents();
|
||||||
|
std::string getFilePath();
|
||||||
|
};
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "TagPlayerControl.hpp"
|
#include "TagPlayerControl.hpp"
|
||||||
|
|
||||||
#include "AudioPlayer.hpp"
|
#include "AudioPlayer.hpp"
|
||||||
|
#include "Tag.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@@ -19,44 +20,22 @@ void TagPlayerControl::onTagChanged(char* tagId) {
|
|||||||
if (tagId == NULL) {
|
if (tagId == NULL) {
|
||||||
// tag has been removed. stop playback
|
// tag has been removed. stop playback
|
||||||
audioPlayer->pause();
|
audioPlayer->pause();
|
||||||
|
storePosition();
|
||||||
} else {
|
} else {
|
||||||
playTag(tagId);
|
playTag(tagId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TagPlayerControl::playTag(char* tagId) {
|
void TagPlayerControl::playTag(char* tagId) {
|
||||||
std::string filePath = "/sdcard/internal/";
|
currentTag = Tag(tagId);
|
||||||
filePath.append(tagId);
|
currentTag.read();
|
||||||
|
|
||||||
std::fstream file(filePath);
|
if (currentTag.isLinked()) {
|
||||||
|
audioPlayer->play(currentTag.getNextLink(), currentTag.getCurrentPosition());
|
||||||
if (! file) {
|
|
||||||
ESP_LOGE(TAG, "Error opening file for tag %s", tagId);
|
|
||||||
|
|
||||||
char* error_name;
|
|
||||||
|
|
||||||
switch (errno)
|
|
||||||
{
|
|
||||||
case EACCES:
|
|
||||||
ESP_LOGE(TAG, "EACCESS");
|
|
||||||
break;
|
|
||||||
case ENOENT:
|
|
||||||
ESP_LOGE(TAG, "ENOENT");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ESP_LOGE(TAG, "not parsed");
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string line;
|
void TagPlayerControl::storePosition() {
|
||||||
std::string content;
|
currentTag.setCurrentPosition(0, audioPlayer->getPosition());
|
||||||
|
currentTag.write();
|
||||||
while(getline(file, line)) {
|
|
||||||
content.append(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
audioPlayer->play(content);
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
}
|
||||||
@@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "AudioPlayer.hpp"
|
#include "AudioPlayer.hpp"
|
||||||
|
#include "Tag.hpp"
|
||||||
|
|
||||||
class TagPlayerControl {
|
class TagPlayerControl {
|
||||||
std::shared_ptr<AudioPlayer> audioPlayer;
|
std::shared_ptr<AudioPlayer> audioPlayer;
|
||||||
|
Tag currentTag;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TagPlayerControl(std::shared_ptr<AudioPlayer> player);
|
TagPlayerControl(std::shared_ptr<AudioPlayer> player);
|
||||||
@@ -13,4 +15,5 @@ class TagPlayerControl {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void playTag(char* tagId);
|
void playTag(char* tagId);
|
||||||
|
void storePosition();
|
||||||
};
|
};
|
||||||
Reference in new issue
Block a user