Extracts handling the Tag-file structure into an own class.

This commit is contained in:
Simon Weidacher
2022-01-02 23:20:53 +01:00
parent 98872d75df
commit e104256985
4 changed files with 217 additions and 33 deletions

View File

@@ -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 ".")

186
device/main/Tag.cpp Normal file
View File

@@ -0,0 +1,186 @@
#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(char* tagId): Tag(std::string(tagId)) {
}
Tag::Tag(std::string tagId): tagId(tagId) {
this->playlist = std::vector<std::string>();
}
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::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;
}

25
device/main/Tag.hpp Normal file
View File

@@ -0,0 +1,25 @@
#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(std::string tagId);
Tag(char* tagId);
void read();
void write();
bool isLinked();
std::string getNextLink();
private:
std::string createFileContents();
std::string readFileContents();
std::string getFilePath();
};

View File

@@ -1,6 +1,7 @@
#include "TagPlayerControl.hpp"
#include "AudioPlayer.hpp"
#include "Tag.hpp"
#include <iostream>
#include <fstream>
@@ -25,38 +26,10 @@ void TagPlayerControl::onTagChanged(char* tagId) {
}
void TagPlayerControl::playTag(char* tagId) {
std::string filePath = "/sdcard/internal/";
filePath.append(tagId);
Tag tag(tagId);
tag.read();
std::fstream file(filePath);
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;
if (tag.isLinked()) {
audioPlayer->play(tag.getNextLink());
}
std::string line;
std::string content;
while(getline(file, line)) {
content.append(line);
}
audioPlayer->play(content);
file.close();
}