From 9a3250d82c0b6adef7c199e6bc0158151510608a Mon Sep 17 00:00:00 2001 From: Julian Rother <julianr@fsmpi.rwth-aachen.de> Date: Wed, 1 Nov 2017 17:41:59 +0100 Subject: [PATCH] Added probe worker --- probe.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 probe.c diff --git a/probe.c b/probe.c new file mode 100644 index 0000000..2b6b01e --- /dev/null +++ b/probe.c @@ -0,0 +1,91 @@ +#include <libavcodec/avcodec.h> +#include <libavformat/avformat.h> + +#include <libxml/tree.h> +#include <libxml/parser.h> +#include <libxml/xpath.h> +#include <libxml/xpathInternals.h> + +#include "util.h" +#include "config.h" + +static char *getxmlattr(xmlAttr *a, char *name, char *err) +{ + for (; a && strcmp(a->name, name); a = a->next); + if (!a) + return err; + return a->children->content; +} + +char *get_xmpchapters(char *xmp) +{ + int i, len, maxlen; + char *out; + xmlDocPtr doc; + xmlXPathContextPtr xpath; + xmlXPathObjectPtr res; + xmlNodePtr node; + double framerate, start; + if (!(doc = xmlParseMemory(xmp, strlen(xmp)))) + return ""; + if (!(xpath = xmlXPathNewContext(doc))) + return ""; + xmlXPathRegisterNs(xpath, "x", "adobe:ns:meta/"); + xmlXPathRegisterNs(xpath, "rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); + xmlXPathRegisterNs(xpath, "xmpDM", "http://ns.adobe.com/xmp/1.0/DynamicMedia/"); + res = xmlXPathEvalExpression("/x:xmpmeta/rdf:RDF/rdf:Description/@xmpDM:videoFrameRate", xpath); + if (!res || !res->nodesetval->nodeNr) + return ""; + framerate = strtod(res->nodesetval->nodeTab[0]->children->content, 0); + xmlXPathFreeObject(res); + res = xmlXPathEvalExpression("/x:xmpmeta/rdf:RDF/rdf:Description/xmpDM:Tracks/rdf:Bag/rdf:li/rdf:Description/xmpDM:markers/rdf:Seq/rdf:li/rdf:Description", xpath); + if (!res || !res->nodesetval) + return ""; + len = 0; maxlen = res->nodesetval->nodeNr*200; + out = malloc(maxlen); + len += xsnprintf(out+len, maxlen-len-1, "["); + for (i = 0; i < res->nodesetval->nodeNr; i ++) + { + start = atoi(getxmlattr(res->nodesetval->nodeTab[i]->properties, "startTime", "0"))/framerate; + if (i) + len += xsnprintf(out+len, maxlen-len-1, ","); + len += xsnprintf(out+len, maxlen-len-1, "{\"time\": %f, \"text\": \"%s\"}", + start, jescape(getxmlattr(res->nodesetval->nodeTab[i]->properties, "name", ""))); + } + len += xsnprintf(out+len, maxlen-len-1, "]"); + return out; +} + +int main(int argc, char *argv[]) +{ + int jobid; + char path[100], *xmp; + AVFormatContext *demux, *mux; + AVDictionaryEntry *tag; + AVDictionary *opts; + if (argc != 5) + return 1; + av_register_all(); + av_log_set_callback(avlogbuf_callback); + + jobid = atoi(argv[1]); + xsnprintf(BL(path), "%s/%s", CONFIG_VIDEOS_RAW, + jstr(jlookup(argv[4], "path"), "")); + ping_job(jobid, "running", 0); + + opts = 0; + av_dict_set_int(&opts, "export_xmp", 1, 0); + demux = 0; + if (avformat_open_input(&demux, path, 0, &opts)) + goto fail; + avformat_find_stream_info(demux, 0); + if (tag = av_dict_get(demux->metadata, "xmp", 0, 0)) + ping_job(jobid, "finished", "{\"xmp_chapters\": %s, \"duration\": %f, \"log\": \"%s\"}", get_xmpchapters(tag->value), demux->duration*av_q2d(AV_TIME_BASE_Q), get_avlogbuf()); + else + ping_job(jobid, "finished", "{\"duration\": %f, \"log\": \"%s\"}", demux->duration*av_q2d(AV_TIME_BASE_Q), get_avlogbuf()); + return 0; + +fail: + ping_job(jobid, "failed", "{\"log\": \"%s\"}", get_avlogbuf()); + return 1; +} -- GitLab