summaryrefslogtreecommitdiff
path: root/httptnt/resourceStreamer.ecpp
diff options
context:
space:
mode:
authormethodus <methodus@web.de>2012-09-29 22:48:56 +0200
committermethodus <methodus@web.de>2012-09-29 22:48:56 +0200
commitdd3e8652f530c35febcc3f595e38443395f79198 (patch)
treeeb4cab34cff88b43aaa657491356ab5f9c7cbde8 /httptnt/resourceStreamer.ecpp
parent97b083ac833ada3c18a5639ee782e575ca583acf (diff)
downloadvdr-plugin-upnp-dd3e8652f530c35febcc3f595e38443395f79198.tar.gz
vdr-plugin-upnp-dd3e8652f530c35febcc3f595e38443395f79198.tar.bz2
Streamer almost completed. First tests successful. However, there are no plugins, yet.
Diffstat (limited to 'httptnt/resourceStreamer.ecpp')
-rw-r--r--httptnt/resourceStreamer.ecpp105
1 files changed, 105 insertions, 0 deletions
diff --git a/httptnt/resourceStreamer.ecpp b/httptnt/resourceStreamer.ecpp
new file mode 100644
index 0000000..2c64fed
--- /dev/null
+++ b/httptnt/resourceStreamer.ecpp
@@ -0,0 +1,105 @@
+<%args>
+objectID;
+int resourceID = 0;
+</%args>
+<%pre>
+#include <string>
+#include <stdint.h>
+#include <limits>
+#include <memory>
+#include "../include/tools.h"
+#include "../include/media/mediaManager.h"
+#include "../include/server.h"
+
+#include <tnt/httpreply.h>
+#include <tnt/httprequest.h>
+#include <tnt/http.h>
+
+using namespace upnp;
+</%pre>
+<#
+int doRequest(tnt::HttpReply reply, tnt::HttpRequest request, std::string objectID, int resourceID) {
+#>
+<%cpp>
+ if(objectID.empty()){
+ reply.out() << "Object ID missing";
+ return HTTP_BAD_REQUEST;
+ }
+
+ cMediaServer* server = cMediaServer::GetInstance();
+ cMediaManager& manager = server->GetManager();
+ std::auto_ptr<cResourceStreamer> streamer(manager.GetResourceStreamer(objectID, resourceID));
+
+ if(!streamer.get()){
+ reply.out() << "Object ID not found or invalid";
+ return HTTP_NOT_FOUND;
+ }
+
+ int code = HTTP_OK;
+
+ reply.setContentType(streamer->GetContentType());
+ reply.setHeader("friendlyName.dlna.org ", server->GetServerDescription().friendlyName);
+ reply.setHeader("contentFeatures.dlna.org ", streamer->GetContentFeatures());
+ reply.setHeader("transferMode.dlna.org ", streamer->GetTransferMode(reply.getHeader("transferMode.dlna.org")));
+
+ if(streamer->GetContentLength() > 0){
+ reply.setContentLengthHeader(streamer->GetContentLength());
+ if(streamer->Seekable()) reply.setHeader("Accept-Ranges", "bytes");
+ }
+
+ if(!request.isMethodHEAD()){
+
+ int offset = 0, length = std::numeric_limits<long>::max();
+ bool hasRange = false;
+
+ if(streamer->Seekable() && streamer->GetContentLength() > 0){
+ if(request.hasHeader("Range")){
+ std::string rangeRequest = request.getHeader("Range");
+ if(rangeRequest.find("bytes=",0) == 0){
+ int minus = rangeRequest.find_first_of('-',6);
+ offset = atoi(rangeRequest.substr(6, minus - 6).c_str());
+ length = atoi(rangeRequest.substr(minus + 1).c_str()) - offset;
+
+ if(length == 0) length = std::numeric_limits<long>::max();
+
+ hasRange = (offset == 0 && length == std::numeric_limits<long>::max()) ? false : true;
+ }
+ }
+
+ streamer->Seek(offset, SEEK_SET);
+ }
+
+ char buffer[KB(16)];
+ ssize_t bytesRead = 0;
+ size_t totalBytesRead = 0;
+ size_t toRead = std::min<size_t>(length, sizeof(buffer));
+ while (0 < (bytesRead = streamer->Read(buffer, toRead)) && length > 0) {
+ reply.out().write(buffer, bytesRead);
+ if (!reply.out()) {
+ code = HTTP_GONE;
+ goto ret;
+ }
+ length -= bytesRead;
+ totalBytesRead += bytesRead;
+ toRead = std::min<size_t>(length, sizeof(buffer));
+ }
+
+ reply.setContentLengthHeader(totalBytesRead);
+
+ if ((bytesRead < 0 || length <= 0) && hasRange) {
+ std::stringstream ss;
+ ss << "bytes " << offset << "-" << offset + totalBytesRead << "/" << streamer->GetContentLength();
+ reply.setHeader("Content-Range", ss.str());
+ code = HTTP_PARTIAL_CONTENT;
+ goto ret;
+ }
+
+ }
+
+ ret:
+ //reply.out() << std::flush;
+ return code;
+</%cpp>
+<#
+}
+#>