提交 4341a93a authored 作者: blu's avatar blu

upload video files

上级 6bee7971
......@@ -68,7 +68,8 @@ private:
thread thEventHandler;
string videoFileServerApi = "http://139.219.142.18:10008/upload/evtvideos/";
bool validMsg(json &msg) {
bool validMsg(json &msg)
{
return true;
}
int handleMsg(vector<vector<uint8_t> > v)
......@@ -91,15 +92,16 @@ private:
gotFormat = true;
spdlog::info("evslicer {} got avformat from {}", selfId, peerId);
}
else if(meta == EV_MSG_META_EVENT){
else if(meta == EV_MSG_META_EVENT) {
data = json::parse(body2str(v[2]));
/// evslicer has two msg interfaces to subsystems on edge side
/// 1. type = "event"; start: timestamp; end: timestamp
/// 2. type = "media"; duration: seconds
if(!validMsg(data)){
if(!validMsg(data)) {
spdlog::info("evslicer {} received invalid msg from {}: {}", selfId, peerId, msg);
}else{
}
else {
spdlog::info("evslicer {} received msg from {}, type = {}, data = {}", selfId, peerId, meta, data.dump());
if(data["type"] == "event") {
lock_guard<mutex> lock(mutEvent);
......@@ -110,7 +112,8 @@ private:
cvEvent.notify_one();
}
}
}else{
}
else {
spdlog::info("evslicer {} received unkown msg from {}: {}", selfId, peerId, msg);
}
}
......@@ -162,7 +165,8 @@ private:
selfId = devSn + ":evslicer:" + to_string(iid);
if(ipc.count("sn") == 0) {
ipcSn = "unkown";
}else{
}
else {
ipcSn = ipc["sn"];
}
......@@ -172,7 +176,7 @@ private:
pullerGid = evpuller["sn"].get<string>() + ":evpuller:" + to_string(evpuller["iid"]);
mgrSn = evmgr["sn"];
if(evslicer.count("path") == 0){
if(evslicer.count("path") == 0) {
spdlog::info("evslicer {} no params for path, using default: {}", selfId, URLOUT_DEFAULT);
urlOut = URLOUT_DEFAULT;
}
......@@ -477,18 +481,21 @@ protected:
}
string getBaseName(const string &fname) {
string getBaseName(const string &fname)
{
string ret;
auto posS = fname.find_last_of('/');
if(posS == string::npos) {
posS = 0;
}else{
}
else {
posS = posS +1;
}
auto posE = fname.find_last_of('.');
if(posE == string::npos) {
posE = fname.size()-1;
}else{
}
else {
posE = posE -1;
}
if(posE < posS) {
......@@ -500,13 +507,15 @@ protected:
return fname.substr(posS, posE - posS + 1);
}
long videoFileName2Ts(string &fileBaseName) {
long videoFileName2Ts(string &fileBaseName)
{
std::tm t;
strptime(fileBaseName.data(), "%Y%m%d_%H%M%S", &t);
return mktime(&t);
}
string videoFileTs2Name(long ts, bool bLog = false) {
string videoFileTs2Name(long ts, bool bLog = false)
{
std::time_t now = ts;
std::tm * ptm = std::localtime(&now);
char buffer[20];
......@@ -598,7 +607,8 @@ protected:
}
// file monitor callback
static void fileMonHandler(const std::vector<event>& evts, void *pUserData) {
static void fileMonHandler(const std::vector<event>& evts, void *pUserData)
{
static string lastFile;
static long lastTs;
......@@ -606,7 +616,8 @@ protected:
for(auto &i : evts) {
if(lastFile == i.get_path()) {
// skip
}else if(!lastFile.empty()){
}
else if(!lastFile.empty()) {
// insert into ts active
//spdlog::info("evslicer {} filemon file: {}, ts: {}, last: {}", self->selfId, i.get_path().c_str(), i.get_time(), lastFile);
if(self->segHead >= self->numSlices) {
......@@ -620,17 +631,19 @@ protected:
}
try{
try {
auto baseName = self->getBaseName(lastFile);
auto ts = self->videoFileName2Ts(baseName);
auto oldTs = self->vTsActive[self->segHead];
self->vTsActive[self->segHead] = ts;
self->segHead++;
//spdlog::info("evslicer {} fileMonHandler video seg done: {}/{}.mp4, ts:{}", self->selfId, self->urlOut, baseName, ts);
}catch(exception &e) {
}
catch(exception &e) {
spdlog::error("evslicer {} fileMonHandler exception: {}", self->selfId, e.what());
}
}else{
}
else {
//nop
}
lastFile = i.get_path();
......@@ -638,14 +651,16 @@ protected:
}
//
int segToIdx(int seg) {
int segToIdx(int seg)
{
if(seg >= numSlices) {
seg -= numSlices;
}
return seg;
}
// find video files
vector<string> findSlicesByRange(long tss, long tse, int offsetS, int offsetE){
vector<string> findSlicesByRange(long tss, long tse, int offsetS, int offsetE)
{
vector<string> ret;
int found = 0;
int _itss = 0;
......@@ -653,7 +668,7 @@ protected:
_itss = segHead;
}
for(int i = 0; i < numSlices; i++){
for(int i = 0; i < numSlices; i++) {
spdlog::info("evslicer {} vector[{}] = {}, {}", selfId, i, vTsActive[i], videoFileTs2Name(vTsActive[i]));
if(vTsActive[i] == 0) {
break;
......@@ -662,21 +677,22 @@ protected:
if(vTsActive[_itss] >= tse || vTsActive[segHead -1] < tss||(!bSegFull && segHead == 0)) {
spdlog::error("evslicer {} findSlicesByRange event range ({},{}) is not in recorded range ({}, {})", selfId, this->videoFileTs2Name(tss), this->videoFileTs2Name(tse), this->videoFileTs2Name(vTsActive[_itss]), this->videoFileTs2Name(vTsActive[segHead -1]));
}else{
}
else {
int idxS, idxE;
int delta = bSegFull? numSlices : 0;
for(int i = segHead + delta; i > _itss; i--){
for(int i = segHead + delta; i > _itss; i--) {
if(vTsActive[segToIdx(i)] == 0) {
continue;
}
if(tse >= vTsActive[segToIdx(i)]){
if((found &1) != 1){
if(tse >= vTsActive[segToIdx(i)]) {
if((found &1) != 1) {
idxE = segToIdx(i);
found |= 1;
}
}
if(tss > vTsActive[segToIdx(i)]){
if(tss > vTsActive[segToIdx(i)]) {
if((found &2) != 2) {
idxS = segToIdx(i);
found |=2;
......@@ -692,7 +708,7 @@ protected:
idxE += numSlices;
}
string sf;
for(int i = idxS; i <= idxE; i++){
for(int i = idxS; i <= idxE; i++) {
int idx = segToIdx(i);
long ts = vTsActive[idx];
string fname = videoFileTs2Name(ts, true);
......@@ -775,12 +791,13 @@ public:
setupStream();
// event thread
thEventHandler = thread([this]{
while(true){
thEventHandler = thread([this] {
while(true)
{
unique_lock<mutex> lk(this->mutEvent);
this->cvEvent.wait(lk, [this]{return !(this->eventQueue.empty());});
this->cvEvent.wait(lk, [this] {return !(this->eventQueue.empty());});
if(this->eventQueue.empty()){
if(this->eventQueue.empty()) {
continue;
}
......@@ -794,11 +811,17 @@ public:
long offsetS = 0;
long offsetE = 0;
// TODO: async
static auto bootTime = chrono::duration_cast<chrono::seconds>(chrono::system_clock::now().time_since_epoch()).count();
if(tse < bootTime) {
spdlog::warn("evslicer {} discard old msg {}", selfId, evt);
return;
}
this_thread::sleep_for(chrono::seconds(this->seconds + 5));
auto v = findSlicesByRange(tss, tse, offsetS, offsetE);
if(v.size() == 0) {
spdlog::error("evslicer {} ignore upload videos in range ({}, {})", this->selfId, this->videoFileTs2Name(tss), this->videoFileTs2Name(tse));
}else{
}
else {
vector<tuple<string, string> > params= {{"startTime", to_string(tss)},{"endTime", to_string(tse)},{"cameraId", ipcSn}, {"headOffset", to_string(offsetS)},{"tailOffset", to_string(offsetE)}};
vector<string> fileNames;
string sf;
......@@ -810,14 +833,13 @@ public:
spdlog::info("evslicer {} file upload url: {}", selfId, this->videoFileServerApi);
// TODO: check result and reschedule it
if(netutils::postFiles(std::move(this->videoFileServerApi), std::move(params), std::move(fileNames)) != 0){
if(netutils::postFiles(std::move(this->videoFileServerApi), std::move(params), std::move(fileNames)) != 0) {
spdlog::error("evslicer {} failed to upload files:\n{}", selfId, sf);
}else{
spdlog::info("evslicer {} successfull uploaded files:\n{}", selfId, sf);
}
#define DEBUG
#ifdef DEBUG
else {
spdlog::info("evslicer {} successfull uploaded files:\n{}", selfId, sf);
#undef DEBUG
#ifdef DEBUG
int iret = 0;
string _path1 = string("/tmp/merged_video/") + this->videoFileTs2Name(tss) + "_" + this->videoFileTs2Name(tse);
fs::path _path(_path1 + ".txt");
......@@ -841,14 +863,22 @@ public:
if(iret < 0) {
spdlog::error("evslicer {} failed to write output {}", selfId, (_path1 + ".mp4").c_str());
}
AVPacket pkt;
while(av_read_frame(_pCtx, &pkt)>=0) {
iret = av_interleaved_write_frame(_pCtx, &pkt);
av_packet_unref(&pkt);
}
av_write_trailer(_pCtx);
if(_pCtx->pb != nullptr)
avio_closep(&_pCtx->pb);
if(_pCtx != nullptr)
avformat_free_context(_pCtx);
#endif
#endif
}
}
}else{
}
else {
spdlog::error("evslicer {} unkown event :{}", this->selfId, evt);
}
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论