From fff7cf97332ea952fbe02ae92a7ddfd5dfbd9f9d Mon Sep 17 00:00:00 2001 From: Erik Zandvliet Date: Tue, 30 Oct 2012 11:15:51 +0100 Subject: [PATCH] Working Smooth? Timestamps x 10.000 --- src/analysers/flv_analyser.cpp | 11 +++++ src/analysers/mp4_analyser.cpp | 6 +++ src/conn_http.cpp | 4 +- src/conn_http_smooth.cpp | 88 ++++++++++++++++++++++------------ 4 files changed, 77 insertions(+), 32 deletions(-) diff --git a/src/analysers/flv_analyser.cpp b/src/analysers/flv_analyser.cpp index 7ac56842..00583338 100644 --- a/src/analysers/flv_analyser.cpp +++ b/src/analysers/flv_analyser.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include //FLV support @@ -18,10 +19,20 @@ int main(int argc, char ** argv) { Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION); conf.parseArgs(argc, argv); FLV::Tag FLV_in; // Temporary storage for incoming FLV data. + std::ofstream vData( "vData" ); + std::ofstream aData( "aData" ); while (!feof(stdin)){ if (FLV_in.FileLoader(stdin)){ std::cout << "Tag: " << FLV_in.tagType() << "\n\tTime: " << FLV_in.tagTime() << std::endl; + if( FLV_in.data[0] == 0x08 ) {//Audio + aData.write( FLV_in.data + 13, FLV_in.len - 17 ); + } + if( FLV_in.data[0] == 0x09 ) {//Video + vData.write( FLV_in.data + 16, FLV_in.len - 20 ); + } } } + vData.close(); + aData.close(); return 0; } diff --git a/src/analysers/mp4_analyser.cpp b/src/analysers/mp4_analyser.cpp index 19ad4292..b8d3bfea 100644 --- a/src/analysers/mp4_analyser.cpp +++ b/src/analysers/mp4_analyser.cpp @@ -23,6 +23,12 @@ int main(int argc, char ** argv) { MP4::Box mp4data; while (mp4data.read(temp)){ std::cerr << mp4data.toPrettyString(0) << std::endl; + if( mp4data.isType( "mdat" ) ) { + std::ofstream oFile; + oFile.open( "mdat" ); + oFile << std::string( mp4data.payload(), mp4data.payloadSize() ); + oFile.close(); + } } return 0; } diff --git a/src/conn_http.cpp b/src/conn_http.cpp index ce00bdf1..974bbec2 100644 --- a/src/conn_http.cpp +++ b/src/conn_http.cpp @@ -318,8 +318,8 @@ namespace Connector_HTTP{ H.SetVar("stream", streamname); return "dynamic"; } - if (url.find("/smooth/") != std::string::npos ) { - std::string streamname = url.substr(8,url.find("/",8)-8); + if (url.find("/smooth/") != std::string::npos && url.find(".ism") != std::string::npos ) { + std::string streamname = url.substr(8,url.find("/",8)-12); Util::Stream::sanitizeName(streamname); H.SetVar("stream", streamname); return "smooth"; diff --git a/src/conn_http_smooth.cpp b/src/conn_http_smooth.cpp index 2536da5f..d7ebb0ed 100644 --- a/src/conn_http_smooth.cpp +++ b/src/conn_http_smooth.cpp @@ -2,6 +2,7 @@ /// Contains the main code for the HTTP Dynamic Connector #include +#include #include #include #include @@ -29,37 +30,42 @@ namespace Connector_HTTP{ std::string BuildManifest(std::string & MovieId, JSON::Value & metadata){ std::stringstream Result; Result << "\n"; - Result << "\n"; + Result << "\n"; if( metadata.isMember( "audio" ) ) { - Result << " \n"; + Result << " \n"; Result << " \n"; - for( int i = 0; i < metadata["keytime"].size(); i++ ) { - Result << " \n"; + for( int i = 0; i < metadata["keytime"].size()-1; i++ ) { + Result << " \n"; + Result << "d=\"" << 10000 * ( metadata["keytime"][i+1].asInt() - metadata["keytime"][i].asInt() ) << "\" />\n"; } + Result << " \n"; Result << " \n"; } if( metadata.isMember( "video" ) ) { - Result << " \n"; + Result << " \n"; Result << " \n"; - for( int i = 0; i < metadata["keytime"].size(); i++ ) { - Result << " \n"; + for( int i = 0; i < metadata["keytime"].size()-1; i++ ) { + Result << " \n"; + Result << "d=\"" << 10000 * ( metadata["keytime"][i+1].asInt() - metadata["keytime"][i].asInt() ) << "\" />\n"; } + Result << " \n"; Result << " \n"; } Result << "\n"; @@ -119,7 +125,7 @@ namespace Connector_HTTP{ #endif conn.setHost(HTTP_R.GetHeader("X-Origin")); if (HTTP_R.url.find("Manifest") == std::string::npos){ - streamname = HTTP_R.url.substr(8,HTTP_R.url.find("/",8)-8); + streamname = HTTP_R.url.substr(8,HTTP_R.url.find("/",8)-12); if (!ss){ ss = Util::Stream::getStream(streamname); if (!ss.connected()){ @@ -139,19 +145,21 @@ namespace Connector_HTTP{ Quality = HTTP_R.url.substr( HTTP_R.url.find("/Q(",8)+3 ); Quality = Quality.substr(0, Quality.find(")")); tempStr = HTTP_R.url.substr( HTTP_R.url.find(")/") + 2 ); + wantsAudio = false; + wantsVideo = false; if( tempStr[0] == 'A' ) { wantsAudio = true; } if( tempStr[0] == 'V' ) { wantsVideo = true; } - tempStr = tempStr.find("(") + 1; + tempStr = tempStr.substr( tempStr.find("(") + 1 ); ReqFragment = atoi( tempStr.substr(0,tempStr.find(")")).c_str() ); #if DEBUG >= 4 - printf( "Quality: %s, Frag %d\n", Quality.c_str(), ReqFragment); + printf( "Quality: %s, Frag %d\n", Quality.c_str(), ( ReqFragment / 10000 ) ); #endif std::stringstream sstream; - sstream << "s " << ReqFragment << "\no \n"; + sstream << "s " << ( ReqFragment / 10000 ) << "\no \n"; ss.SendNow(sstream.str().c_str()); Flash_RequestPending++; }else{ - streamname = HTTP_R.url.substr(8,HTTP_R.url.find("/",8)-8); + streamname = HTTP_R.url.substr(8,HTTP_R.url.find("/",8)-12); if (!Strm.metadata.isNull()){ HTTP_S.Clean(); HTTP_S.SetHeader("Content-Type","text/xml"); @@ -257,23 +265,24 @@ namespace Connector_HTTP{ MP4::TRUN trun_box; //maybe reinsert dataOffset - trun_box.setFlags( MP4::trunfirstSampleFlags | MP4::trunsampleDuration | MP4::trunsampleSize ); + std::cerr << "Setting Flags: " << (MP4::trundataOffset | MP4::trunfirstSampleFlags | MP4::trunsampleDuration | MP4::trunsampleSize) << std::endl; + trun_box.setFlags( MP4::trundataOffset | MP4::trunfirstSampleFlags | MP4::trunsampleDuration | MP4::trunsampleSize ); + trun_box.setDataOffset( 42 ); trun_box.setFirstSampleFlags( MP4::isIPicture | MP4::noDisposable | MP4::isKeySample ); std::deque< std::string >::iterator FlashBufIter = FlashBuf.begin(); for( int i = 0; i < FlashBuf.size(); i++ ) { MP4::trunSampleInformation trunSample; trunSample.sampleSize = (*FlashBufIter).size(); - trunSample.sampleDuration = Timestamps[i+1]-Timestamps[i]; + trunSample.sampleDuration = (Timestamps[i+1]-Timestamps[i]) * 10000; trun_box.setSampleInformation( trunSample, i ); FlashBufIter ++; } - MP4::Box sdtp_box; - sdtp_box.setType( "sdtp" ); - sdtp_box.setInt32( 0, 0 ); - sdtp_box.setInt8( 0x24, 4 ); + MP4::SDTP sdtp_box; + sdtp_box.setVersion( 0 ); + sdtp_box.setValue( 0x24, 4 ); for( int i = 1; i < FlashBuf.size(); i++ ) { - sdtp_box.setInt8( 0x14, i+4 ); + sdtp_box.setValue( 0x14, 4+i ); } MP4::TRAF traf_box; @@ -285,6 +294,15 @@ namespace Connector_HTTP{ moof_box.setContent( mfhd_box, 0 ); moof_box.setContent( traf_box, 1 ); + //setting tha offsets! + trun_box.setDataOffset(moof_box.boxedSize() + 8); + traf_box.setContent( trun_box, 1 ); + moof_box.setContent( traf_box, 1 ); + + + //std::cerr << "\t[encoded] = " << ((MP4::TRUN&)(((MP4::TRAF&)(moof_box.getContent(1))).getContent(1))).getDataOffset() << std::endl; + + HTTP_S.SetHeader("Content-Length", FlashBufSize+8+moof_box.boxedSize());//32+33+btstrp.size()); conn.SendNow(HTTP_S.BuildResponse("200", "OK")); @@ -306,14 +324,24 @@ namespace Connector_HTTP{ FlashBuf.clear(); FlashBufSize = 0; } - if ( wantsVideo && Strm.lastType() == DTSC::VIDEO ) { + if ( wantsAudio && Strm.lastType() == DTSC::AUDIO ) { FlashBuf.push_back( Strm.lastData() ); FlashBufSize += Strm.lastData().size(); Timestamps.push_back( Strm.getPacket(0)["time"].asInt() ); } - if ( wantsAudio && Strm.lastType() == DTSC::AUDIO ) { - FlashBuf.push_back( Strm.lastData() ); - FlashBufSize += Strm.lastData().size(); + if ( wantsVideo && Strm.lastType() == DTSC::VIDEO ) { + std::stringstream myStream; + std::string myData = Strm.lastData(); + //while( myData.size() ) { + // myStream << (char)0x00 << (char)0x00 << (char)0x00 << (char)0x01; + // int myLen = ( myData[0] << 24 ) + ( myData[1] << 16 ) + ( myData[2] << 8 ) + myData[3]; + // myStream << myData.substr( 4, myLen ); + // myData.erase( 0, myLen + 4 ); + //} + //FlashBuf.push_back( myStream.str() ); + FlashBuf.push_back( myData ); + //FlashBufSize += myStream.str().size(); + FlashBufSize += myData.size(); Timestamps.push_back( Strm.getPacket(0)["time"].asInt() ); } }