//--------------------------------------------------------------------------- void File_Ttml::Read_Buffer_Continue() { #if MEDIAINFO_DEMUX Demux(Buffer, Buffer_Size, ContentType_MainStream); #endif //MEDIAINFO_DEMUX // Output #if MEDIAINFO_EVENTS for (; p; p=p->NextSiblingElement()) { //p if (!strcmp(p->Value(), "p")) { const char* Attribute; int64u DTS_Begin=(int64u)-1; Attribute=p->Attribute("begin"); if (Attribute) DTS_Begin=Ttml_str2timecode(Attribute); int64u DTS_End=(int64u)-1; Attribute=p->Attribute("end"); if (Attribute) DTS_End=Ttml_str2timecode(Attribute); Ztring Content; if (p->FirstChild()) Content.From_UTF8(p->FirstChild()->Value()); Frame_Count++; } } #endif MEDIAINFO_EVENTS Buffer_Offset=Buffer_Size; }
//--------------------------------------------------------------------------- void File_Eia608::XDS_Channel_NetworkName() { string ValueS; for (size_t Pos=2; Pos<XDS_Data.size()-2; Pos++) ValueS.append(1, (const char)(XDS_Data[Pos])); Ztring Value; Value.From_UTF8(ValueS.c_str()); Element_Info(_T("Network Name=")+Value); }
//--------------------------------------------------------------------------- void File_Eia608::XDS_Current_ProgramName() { string ValueS; for (size_t Pos=2; Pos<XDS_Data[XDS_Level].size()-2; Pos++) ValueS.append(1, (const char)(XDS_Data[XDS_Level][Pos])); Ztring Value; Value.From_UTF8(ValueS.c_str()); Element_Info1(__T("Program Name=")+Value); }
//--------------------------------------------------------------------------- // Load CSV bool ZtringListListF::CSV_Charger () { //Read file File F; if (!F.Open(Name)) return false; int8u* Buffer=new int8u[(size_t)F.Size_Get()+1]; size_t BytesCount=F.Read(Buffer, (size_t)F.Size_Get()); F.Close(); if (BytesCount==Error) { delete[] Buffer; //Buffer=NULL; return false; } Buffer[(int32u)BytesCount]=(int8u)'\0'; //Convert file in UTF-8 or Local Ztring File; if (!Local) { //UTF-8 File.From_UTF8((char*)Buffer, 0, BytesCount); #ifdef _DEBUG if (File.size()==0) File.From_Local((char*)Buffer, 0, BytesCount); #endif //_DEBUG } if (File.size()==0) //Local of UTF-8 failed File.From_Local((char*)Buffer, 0, BytesCount); //Separators if (Separator[0]==__T("(Default)")) Separator[0]=EOL; Ztring SeparatorT=Separator[1]; Separator[1]=__T(";"); //Writing Write(File); //Separators Separator[1]=SeparatorT; delete[] Buffer; //Buffer=NULL; return true; }
void File_OtherText::Read_Buffer_Continue() { if (Buffer_Size<0x200) { Element_WaitForMoreData(); return; } Element_Offset=File_Size-(File_Offset+Buffer_Offset); Ztring Format, FormatMore, Codec; Ztring File; ZtringList Lines; //Feed File and Lines File.From_UTF8((const char*)Buffer, Buffer_Size>65536?65536:Buffer_Size); if (File.empty()) File.From_Local((const char*)Buffer, Buffer_Size>65536?65536:Buffer_Size); // Trying from local code page if (File.size()<0x100) { File.From_Unicode((wchar_t*)Buffer, 0, Buffer_Size/sizeof(wchar_t)); //Unicode with BOM //TODO: Order of bytes (big or Little endian) if (File.size()<0x100) { Reject("Other text"); return; } } if (File.size()>0x1000) File.resize(0x1000); //Do not work on too big File.FindAndReplace(__T("\r\n"), __T("\n"), 0, Ztring_Recursive); File.FindAndReplace(__T("\r"), __T("\n"), 0, Ztring_Recursive); Lines.Separator_Set(0, __T("\n")); Lines.Write(File); Lines.resize(0x20); if (Lines[0]==__T("[Script Info]") && (Lines.Find(__T("ScriptType: v4.00"))!=Error || Lines.Find(__T("Script Type: V4.00"))!=Error) && Lines.Find(__T("[V4 Styles]"))!=Error ) { Format=__T("SSA"); FormatMore=__T("SubStation Alpha"); Codec=__T("SSA"); } else if (Lines[0]==__T("[Script Info]") && (Lines.Find(__T("ScriptType: v4.00+"))!=Error || Lines.Find(__T("Script Type: V4.00+"))!=Error) && Lines.Find(__T("[V4+ Styles]"))!=Error ) { Format=__T("ASS"); FormatMore=__T("Advanced SubStation Alpha"); Codec=__T("ASS"); } else if (Lines[0].size()>24 && Lines[0][ 0]==__T('0') && Lines[0][ 1]==__T('0') && Lines[0][ 2]==__T(':') && Lines[0][ 5]==__T(':') && Lines[0][ 8]==__T(':') && Lines[0][11]==__T(' ') && Lines[0][12]==__T('0') && Lines[0][13]==__T('0') && Lines[0][14]==__T(':') && Lines[0][17]==__T(':') && Lines[0][20]==__T(':') && Lines[0][23]==__T(' ') ) { Format=__T("Adobe encore DVD"); Codec=__T("Adobe"); } else if (Lines[0].size()==11 && Lines[0][0]==__T('-') && Lines[0][1]==__T('-') && Lines[0][2]==__T('>') && Lines[0][3]==__T('>') && Lines[0][4]==__T(' ') && Lines[0][5]==__T('0') && Lines[1].empty()!=true ) { Format=__T("AQTitle"); Codec=__T("AQTitle"); } else if (Lines[0].size()>28 && Lines[0][ 0]==__T('0') && Lines[0][ 1]==__T('0') && Lines[0][ 2]==__T(':') && Lines[0][ 5]==__T(':') && Lines[0][ 8]==__T(':') && Lines[0][11]==__T(' ') && Lines[0][12]==__T(',') && Lines[0][13]==__T(' ') && Lines[0][14]==__T('0') && Lines[0][15]==__T('0') && Lines[0][16]==__T(':') && Lines[0][19]==__T(':') && Lines[0][22]==__T(':') && Lines[0][25]==__T(' ') && Lines[0][16]==__T(',') && Lines[0][27]==__T(' ') ) { Format=__T("Captions 32"); Codec=__T("Caption 32"); } else if (Lines[0].size()==23 && Lines[0]==__T("*Timecode type: PAL/EBU") && Lines[1].empty() && Lines[2].size()==23 && Lines[2][ 0]==__T('0') && Lines[2][ 1]==__T('0') && Lines[2][ 2]==__T(':') && Lines[2][ 5]==__T(':') && Lines[2][ 8]==__T(':') && Lines[2][11]==__T(' ') && Lines[2][12]==__T('0') && Lines[2][13]==__T('0') && Lines[2][14]==__T(':') && Lines[2][17]==__T(':') && Lines[2][20]==__T(':') && Lines[2].size()>0 ) { Format=__T("Captions Inc"); Codec=__T("Captions inc"); } else if (Lines[0].size()>1 && Lines[0][0]==__T('*') && Lines.Find(__T("** Caption Number 1"))!=Error ) { Format=__T("Cheeta"); } else if (Lines[0].size()>10 && Lines[0][0]==__T('~') && Lines[0][1]==__T('C') && Lines[0][2]==__T('P') && Lines[0][3]==__T('C') && Lines[0][9]==__T('~') && Lines[1][ 0]==__T('0') && Lines[1][ 1]==__T('0') && Lines[1][ 2]==__T(':') && Lines[1][ 5]==__T(':') && Lines[1][ 8]==__T(':') ) { Format=__T("CPC Captioning"); Codec=__T("CPC Captioning"); } else if (Lines[0].find(__T("<SAMI>"))==0) { Format=__T("SAMI"); } else return; if (Format.empty()) return; Accept("Other text"); if (!IsSub) { Fill(Stream_General, 0, General_Format, Format); Fill(Stream_General, 0, General_Format_Info, FormatMore, true); } Stream_Prepare(Stream_Text); Fill(Stream_Text, 0, Text_Format, Format); Fill(Stream_Text, 0, Text_Codec, Codec); //No more need data Element_Begin1(Format); Element_End0(); Finish("Other text"); }
//--------------------------------------------------------------------------- bool File_Hls::FileHeader_Begin() { //Element_Size if (File_Size>1024*1024 || File_Size<10) { Reject("HLS"); return false; //HLS files are not big } if (Buffer_Size<File_Size) return false; //Wait for complete file Ztring Document; Document.From_UTF8((char*)Buffer, Buffer_Size); ZtringList Lines; size_t LinesSeparator_Pos=Document.find_first_of(__T("\r\n")); if (LinesSeparator_Pos>File_Size-1) { Reject("HLS"); return false; } Ztring LinesSeparator; if (Document[LinesSeparator_Pos]==__T('\r') && LinesSeparator_Pos+1<Document.size() && Document[LinesSeparator_Pos+1]==__T('\n')) LinesSeparator=__T("\r\n"); else if (Document[LinesSeparator_Pos]==__T('\r')) LinesSeparator=__T("\r"); else if (Document[LinesSeparator_Pos]==__T('\n')) LinesSeparator=__T("\n"); else { Reject("HLS"); return false; } Lines.Separator_Set(0, LinesSeparator); Lines.Write(Document); if (Lines(0)!=__T("#EXTM3U")) { Reject("HLS"); return false; } Accept("HLS"); Fill(Stream_General, 0, General_Format, "HLS"); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); if (!IsSub) ReferenceFiles->ContainerHasNoId=true; File__ReferenceFilesHelper::reference ReferenceFile; bool IsGroup=false; for (size_t Line=0; Line<Lines.size(); Line++) { if (!Lines[Line].empty()) { if (Lines[Line].find(__T("#EXT-X-STREAM-INF"))==0) IsGroup=true; else if (Lines[Line][0]==__T('#')) ; else { if (IsGroup) { File__ReferenceFilesHelper::reference ReferenceStream; ReferenceStream.FileNames.push_back(Lines[Line]); ReferenceStream.StreamID=ReferenceFiles->References.size()+1; ReferenceFiles->References.push_back(ReferenceStream); IsGroup=false; #if MEDIAINFO_EVENTS ParserIDs[0]=MediaInfo_Parser_HlsIndex; StreamIDs_Width[0]=sizeof(size_t)*2; #endif //MEDIAINFO_EVENTS } else ReferenceFile.FileNames.push_back(Lines[Line]); } } } if (ReferenceFiles->References.empty()) { ReferenceFiles->References.push_back(ReferenceFile); ReferenceFiles->TestContinuousFileNames=true; } Element_Offset=File_Size; //All should be OK... return true; }
//--------------------------------------------------------------------------- bool File_SubRip::FileHeader_Begin() { if (!IsSub && (Buffer_Size<File_Size && Buffer_Size<65536)) { Element_WaitForMoreData(); return false; } ZtringListList List; List.Separator_Set(0, __T("\n\n")); List.Separator_Set(1, __T("\n")); if (Buffer[0]==0xEF && Buffer[1]==0xBB && Buffer[2]==0xBF) HasBOM=true; bool IsLocal=false; Ztring Temp; Temp.From_UTF8((const char*)Buffer+(HasBOM?3:0), (Buffer_Size>65536?65536:Buffer_Size)-(HasBOM?3:0)); if (Temp.empty()) { Temp.From_Local((const char*)Buffer+(HasBOM?3:0), (Buffer_Size>65536?65536:Buffer_Size)-(HasBOM?3:0)); // Trying from local code page IsLocal=true; } Temp.FindAndReplace(__T("\r\n"), __T("\n"), 0, Ztring_Recursive); Temp.FindAndReplace(__T("\r"), __T("\n"), 0, Ztring_Recursive); List.Write(Temp); if (List(0, 0)==__T("WEBVTT FILE") || List(0, 0)==__T("WEBVTT")) IsVTT=true; if (!IsVTT) { size_t IsOk=0; size_t IsNok=0; for (size_t Pos=0; Pos<List.size(); Pos++) { if (List(Pos, 0).To_int64u()==Pos+1) IsOk++; else IsNok++; if (List(Pos, 1).size()>22 && List(Pos, 1)[2]==__T(':') && List(Pos, 1)[5]==__T(':') && List(Pos, 1).find(__T(" --> "))!=string::npos) IsOk++; else IsNok++; } if (!IsOk || IsNok>IsOk/2) { Reject(); return true; } } if (!IsSub && File_Size!=(int64u)-1 && Buffer_Size!=File_Size) { Element_WaitForMoreData(); return false; } if (!Status[IsAccepted]) { Accept(); Fill(Stream_General, 0, General_Format, IsVTT?"WebVTT":"SubRip"); Stream_Prepare(Stream_Text); Fill(Stream_Text, 0, "Format", IsVTT?"WebVTT":"SubRip"); Fill(Stream_Text, 0, "Codec", IsVTT?"WebVTT":"SubRip"); } if (IsLocal) Temp.From_Local((const char*)Buffer+(HasBOM?3:0), Buffer_Size-(HasBOM?3:0)); else Temp.From_UTF8((const char*)Buffer+(HasBOM?3:0), Buffer_Size-(HasBOM?3:0)); Temp.FindAndReplace(__T("\r\n"), __T("\n"), 0, Ztring_Recursive); Temp.FindAndReplace(__T("\r"), __T("\n"), 0, Ztring_Recursive); List.Write(Temp); #if MEDIAINFO_DEMUX size_t Pos=0; for (;;) { if (Pos>=List.size()) break; if (List[Pos].size()>=3 || (IsVTT && List[Pos].size()>=2)) { Ztring PTS_Begin_String=List[Pos][IsVTT?0:1].SubString(Ztring(), __T(" --> ")); Ztring PTS_End_String=List[Pos][IsVTT?0:1].SubString(__T(" --> "), Ztring()); if (IsVTT) { size_t Extra_Pos=PTS_End_String.find(__T(' ')); if (Extra_Pos!=string::npos) PTS_End_String.resize(Extra_Pos); //Discarding positioning } item Item; Item.PTS_Begin=SubRip_str2timecode(PTS_Begin_String.To_UTF8().c_str()); Item.PTS_End=SubRip_str2timecode(PTS_End_String.To_UTF8().c_str()); for (size_t Pos2=IsVTT?1:2; Pos2<List[Pos].size(); Pos2++) { List[Pos][Pos2].Trim(); Item.Content+=List[Pos][Pos2]; if (Pos2+1<List[Pos].size()) Item.Content+=EOL; } Items.push_back(Item); } Pos++; } #endif //MEDIAINFO_DEMUX return true; }
//--------------------------------------------------------------------------- bool File_Pdf::Get_Next(string &Key, Ztring &Value) { Key.clear(); Value.clear(); string Line; //Removig end of lines while (Element_Offset<Element_Size && (Buffer[Buffer_Offset+(size_t)Element_Offset]=='\r' || Buffer[Buffer_Offset+(size_t)Element_Offset]=='\n' || Buffer[Buffer_Offset+(size_t)Element_Offset]==' ')) Element_Offset++; //End if (Element_Offset>=Element_Size) return true; //Testing Catalog Peek_String (2, Line); if (Line=="<<") { Element_Offset+=2; Catalog_Level++; return true; } else if (Line==">>") { Element_Offset+=2; Catalog_Level--; return true; } //Getting a complete line Peek_String (SizeOfLine(), Line); //Testing Catalog size_t Catalog_End=Line.find(">>"); if (Catalog_End!=String::npos) Line.resize(Catalog_End); //Testing stream if (Line=="stream") { Skip_String(Line.size(), "Stream, Header"); Key=Line; return false; } if (Line=="endstream") { Skip_String(Line.size(), "Stream, Footer"); Key=Line; return false; } //Testing object if (Line=="endobj") { Skip_String(Line.size(), "Footer"); Key=Line; return false; } //Base int64u Line_Base=Element_Offset; //Testing next key size_t Line_End=0; size_t Line_Begin=Line_End; // Key-Value if (Line_Begin<Line.size() && Line[Line_Begin]=='/') { Line_End= Line_Begin+1; size_t HasParenthesis=0; size_t HasBracket=0; size_t HasSpace=0; size_t HasValue=0; for (;;) { if (Line_End==Line.size()) break; if (!HasParenthesis && !HasBracket && HasValue && Line[Line_End]=='<' && Line_End+1<Line.size() && Line[Line_End+1]=='<') break; if (!HasParenthesis && !HasBracket && HasValue && Line[Line_End]=='/') break; else if (!HasValue && Line[Line_End]=='/') ++HasValue; else if (!HasValue && HasSpace) ++HasValue; if (Line[Line_End]==' ') ++HasSpace; if (Line[Line_End]=='(') ++HasParenthesis; if (HasParenthesis && Line[Line_End]==')') --HasParenthesis; if (Line[Line_End]=='[') ++HasBracket; if (HasBracket && Line[Line_End]==']') --HasBracket; ++Line_End; } while(Line_End && Line[Line_End-1]==' ') Line_End--; //Removing trailing spaces Element_Offset=Line_Base+Line_Begin; string KeyValue; Get_String(Line_End-Line_Begin, KeyValue, "Key-Value"); size_t Key_Max=KeyValue.find_first_of(" ("); if (Key_Max==string::npos) Key_Max=KeyValue.size(); Key=KeyValue.substr(1, Key_Max-1); size_t Value_Min=Key_Max; while (Value_Min<KeyValue.size() && KeyValue[Value_Min]==' ') ++Value_Min; if (Value_Min<KeyValue.size() && KeyValue[Value_Min]=='(') { ++Value_Min; size_t Value_Max=KeyValue.find(')', Value_Min); if (Value_Max!=string::npos) { //TODO Value.From_UTF8(KeyValue.c_str()+Value_Min, Value_Max-Value_Min); } else Value.From_UTF8(KeyValue.c_str()+Value_Min); } else Value.From_UTF8(KeyValue.c_str()+Value_Min); return false; } return false; }
//--------------------------------------------------------------------------- bool File_Dxw::FileHeader_Begin() { //Element_Size if (File_Size>64*1024) { Reject("DXW"); return false; //DXW files are not big } //Element_Size if (Buffer_Size<5) return false; //Must wait for more data //XML header if (Buffer[0]!='<' || Buffer[1]!='?' || Buffer[2]!='x' || Buffer[3]!='m' || Buffer[4]!='l') { Reject("DXW"); return false; } TiXmlDocument document(File_Name.To_Local()); if (document.LoadFile()) { TiXmlElement* Root=document.FirstChildElement("indexFile"); if (Root) { const char* Attribute=Root->Attribute("xmlns"); if (Attribute==NULL || Ztring().From_UTF8(Attribute)!=_T("urn:digimetrics-xml-wrapper")) { Reject("DXW"); Reject(); } Accept("DXW"); Fill(Stream_General, 0, General_Format, "DXW"); File_Size_Total=File_Size; TiXmlElement* Track=Root->FirstChildElement(); while (Track) { if (Track->ValueStr()=="clip") { Attribute=Track->Attribute("file"); if (Attribute) { reference Reference_Temp; Reference_Temp.FileName.From_UTF8(Attribute); Attribute=Track->Attribute("type"); if (Attribute) { Ztring StreamKind; StreamKind.From_UTF8(Attribute); if (StreamKind==_T("video")) Reference_Temp.StreamKind=Stream_Video; if (StreamKind==_T("audio")) Reference_Temp.StreamKind=Stream_Audio; if (StreamKind==_T("data")) Reference_Temp.StreamKind=Stream_Text; //Not sure this is a right mapping, but this is only used when file is missing } References.push_back(Reference_Temp); File_Dxw::Reference=References.begin(); MI=NULL; } } Track=Track->NextSiblingElement(); } } else { Reject("DXW"); return false; } } else { Reject("DXW"); return false; } //All should be OK... return true; }
//--------------------------------------------------------------------------- void File_Ttml::Read_Buffer_Continue() { tinyxml2::XMLDocument document; if (!FileHeader_Begin_XML(document)) return; XMLElement* Root=document.FirstChildElement("tt"); if (!Root) { Reject(); return; } if (!Status[IsAccepted]) { Accept(); #if MEDIAINFO_EVENTS MuxingMode=(int8u)-1; if (StreamIDs_Size>=2 && ParserIDs[StreamIDs_Size-2]==MediaInfo_Parser_Mpeg4) MuxingMode=11; //MPEG-4 #endif MEDIAINFO_EVENTS } tinyxml2::XMLElement* div=NULL; #if MEDIAINFO_EVENTS tinyxml2::XMLElement* p=NULL; #endif //MEDIAINFO_EVENTS for (XMLElement* tt_element=Root->FirstChildElement(); tt_element; tt_element=tt_element->NextSiblingElement()) { //body if (!strcmp(tt_element->Value(), "body")) { for (XMLElement* body_element=tt_element->FirstChildElement(); body_element; body_element=body_element->NextSiblingElement()) { //div if (!strcmp(body_element->Value(), "div")) { for (XMLElement* div_element=body_element->FirstChildElement(); div_element; div_element=div_element->NextSiblingElement()) { //p if (!strcmp(div_element->Value(), "p")) { div=body_element; #if MEDIAINFO_EVENTS p=div_element; #endif //MEDIAINFO_EVENTS break; } } if (div) break; } } if (div) break; } } #if MEDIAINFO_DEMUX Demux(Buffer, Buffer_Size, ContentType_MainStream); #endif //MEDIAINFO_DEMUX // Output #if MEDIAINFO_EVENTS for (; p; p=p->NextSiblingElement()) { //p if (!strcmp(p->Value(), "p")) { const char* Attribute; int64u DTS_Begin=(int64u)-1; Attribute=p->Attribute("begin"); if (Attribute) DTS_Begin=Ttml_str2timecode(Attribute); int64u DTS_End=(int64u)-1; Attribute=p->Attribute("end"); if (Attribute) DTS_End=Ttml_str2timecode(Attribute); Ztring Content; if (p->FirstChild()) Content.From_UTF8(p->FirstChild()->Value()); Frame_Count++; } } #endif MEDIAINFO_EVENTS Buffer_Offset=Buffer_Size; }
//--------------------------------------------------------------------------- bool File_Dxw::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; { XMLElement* Root=document.FirstChildElement("indexFile"); if (Root) { const char* Attribute=Root->Attribute("xmlns"); if (Attribute==NULL || Ztring().From_UTF8(Attribute)!=__T("urn:digimetrics-xml-wrapper")) { Reject("DXW"); return false; } Accept("DXW"); Fill(Stream_General, 0, General_Format, "DXW"); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); XMLElement* Track=Root->FirstChildElement(); while (Track) { if (string(Track->Value())=="clip") { File__ReferenceFilesHelper::reference ReferenceFile; Attribute=Track->Attribute("file"); if (Attribute) { ReferenceFile.FileNames.push_back(Ztring().From_UTF8(Attribute)); Attribute=Track->Attribute("type"); if (Attribute) { Ztring StreamKind; StreamKind.From_UTF8(Attribute); if (StreamKind==__T("video")) ReferenceFile.StreamKind=Stream_Video; if (StreamKind==__T("audio")) ReferenceFile.StreamKind=Stream_Audio; if (StreamKind==__T("data")) ReferenceFile.StreamKind=Stream_Text; //Not sure this is a right mapping, but this is only used when file is missing } ReferenceFile.StreamID=ReferenceFiles->References.size()+1; } Attribute=Track->Attribute("framerate"); if (Attribute) { ReferenceFile.FrameRate=Ztring().From_UTF8(Attribute).To_float64(); Attribute=Track->Attribute("type"); if (Attribute) { Ztring StreamKind; StreamKind.From_UTF8(Attribute); if (StreamKind==__T("video")) ReferenceFile.StreamKind=Stream_Video; if (StreamKind==__T("audio")) ReferenceFile.StreamKind=Stream_Audio; if (StreamKind==__T("data")) ReferenceFile.StreamKind=Stream_Text; //Not sure this is a right mapping, but this is only used when file is missing } XMLElement* Frame=Track->FirstChildElement(); while (Frame) { if (string(Frame->Value())=="frame") { Attribute=Frame->Attribute("file"); if (Attribute) ReferenceFile.FileNames.push_back(Ztring().From_UTF8(Attribute)); } Frame=Frame->NextSiblingElement(); } } ReferenceFile.StreamID=ReferenceFiles->References.size()+1; ReferenceFiles->References.push_back(ReferenceFile); } Track=Track->NextSiblingElement(); } } else { Reject("DXW"); return false; } } //All should be OK... return true; }
//--------------------------------------------------------------------------- void File_Ttml::Read_Buffer_Continue() { tinyxml2::XMLDocument document; if (!FileHeader_Begin_XML(document)) return; XMLElement* Root=document.FirstChildElement("tt"); if (!Root) { Reject(); return; } if (!Status[IsAccepted]) { Accept(); #if MEDIAINFO_EVENTS MuxingMode=(int8u)-1; if (StreamIDs_Size>=2 && ParserIDs[StreamIDs_Size-2]==MediaInfo_Parser_Mpeg4) MuxingMode=11; //MPEG-4 if (StreamIDs_Size>2 && ParserIDs[StreamIDs_Size-2]==MediaInfo_Parser_Mxf) //Only if referenced MXF MuxingMode=13; //MXF #endif //MEDIAINFO_EVENTS #if MEDIAINFO_DEMUX && MEDIAINFO_NEXTPACKET if (Config->NextPacket_Get() && Config->Event_CallBackFunction_IsSet()) return; // Waiting for NextPacket #endif //MEDIAINFO_DEMUX && MEDIAINFO_NEXTPACKET } tinyxml2::XMLElement* div=NULL; #if MEDIAINFO_EVENTS tinyxml2::XMLElement* p=NULL; #endif //MEDIAINFO_EVENTS for (XMLElement* tt_element=Root->FirstChildElement(); tt_element; tt_element=tt_element->NextSiblingElement()) { //body if (!strcmp(tt_element->Value(), "body")) { for (XMLElement* body_element=tt_element->FirstChildElement(); body_element; body_element=body_element->NextSiblingElement()) { //div if (!strcmp(body_element->Value(), "div")) { for (XMLElement* div_element=body_element->FirstChildElement(); div_element; div_element=div_element->NextSiblingElement()) { //p if (!strcmp(div_element->Value(), "p")) { div=body_element; #if MEDIAINFO_EVENTS p=div_element; #endif //MEDIAINFO_EVENTS break; } } if (div) break; } } if (div) break; } } #if MEDIAINFO_DEMUX Demux(Buffer, Buffer_Size, ContentType_MainStream); #endif //MEDIAINFO_DEMUX // Output #if MEDIAINFO_EVENTS for (; p; p=p->NextSiblingElement()) { //p if (!strcmp(p->Value(), "p")) { int64u DTS_Begin=(int64u)-1; const char* Attribute=p->Attribute("begin"); if (Attribute) DTS_Begin=Ttml_str2timecode(Attribute); int64u DTS_End=(int64u)-1; Attribute=p->Attribute("end"); if (Attribute) DTS_End=Ttml_str2timecode(Attribute); string ContentUtf8; XMLPrinter printer; p->Accept(&printer); ContentUtf8+=printer.CStr(); while (!ContentUtf8.empty() && (ContentUtf8[ContentUtf8.size()-1]=='\r' || ContentUtf8[ContentUtf8.size()-1]=='\n')) ContentUtf8.resize(ContentUtf8.size()-1); Ztring Content; Content.From_UTF8(ContentUtf8.c_str()); Frame_Count_NotParsedIncluded=Frame_Count; EVENT_BEGIN (Global, SimpleText, 0) //Hack: remove "p", "span", "br" Content.FindAndReplace(__T("\r"), Ztring(), 0, ZenLib::Ztring_Recursive); Content.FindAndReplace(__T("\n"), Ztring(), 0, ZenLib::Ztring_Recursive); for (;;) { size_t Span_Begin=Content.find(__T("<p")); if (Span_Begin==string::npos) break; size_t Span_End=Content.find(__T(">"), Span_Begin+5); if (Span_End==string::npos) break; size_t ShlashSpan_Begin=Content.find(__T("</p>"), Span_End+1); if (ShlashSpan_Begin==string::npos) break; Content.erase(ShlashSpan_Begin, 7); Content.erase(Span_Begin, Span_End-Span_Begin+1); } for (;;) { size_t Span_Begin=Content.find(__T("<span")); if (Span_Begin==string::npos) break; size_t Span_End=Content.find(__T(">"), Span_Begin+5); if (Span_End==string::npos) break; size_t ShlashSpan_Begin=Content.find(__T("</span>"), Span_End+1); if (ShlashSpan_Begin==string::npos) break; Content.erase(ShlashSpan_Begin, 7); Content.erase(Span_Begin, Span_End-Span_Begin+1); } Content.FindAndReplace(__T("<br>"), EOL, 0, ZenLib::Ztring_Recursive); Content.FindAndReplace(__T("<br/>"), EOL, 0, ZenLib::Ztring_Recursive); Content.FindAndReplace(__T("<br />"), EOL, 0, ZenLib::Ztring_Recursive); Event.DTS=DTS_Begin; Event.PTS=Event.DTS; Event.DUR=DTS_End-DTS_Begin; Event.Content=Content.c_str(); Event.Flags=0; Event.MuxingMode=MuxingMode; Event.Service=(int8u)Element_Code; Event.Row_Max=0; Event.Column_Max=0; Event.Row_Values=NULL; Event.Row_Attributes=NULL; EVENT_END () EVENT_BEGIN (Global, SimpleText, 0) Event.DTS=DTS_End; Event.PTS=Event.DTS; Event.DUR=0; Event.Content=__T(""); Event.Flags=0; Event.MuxingMode=MuxingMode; Event.Service=(int8u)Element_Code; Event.Row_Max=0; Event.Column_Max=0; Event.Row_Values=NULL; Event.Row_Attributes=NULL; EVENT_END () Frame_Count++; } } #endif //MEDIAINFO_EVENTS Buffer_Offset=Buffer_Size; }
//--------------------------------------------------------------------------- bool File_Dxw::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; { XMLElement* Root=document.FirstChildElement("indexFile"); if (Root) { const char* Attribute=Root->Attribute("xmlns"); if (Attribute==NULL || Ztring().From_UTF8(Attribute)!=__T("urn:digimetrics-xml-wrapper")) { Reject("DXW"); return false; } Accept("DXW"); Fill(Stream_General, 0, General_Format, "DXW"); ReferenceFiles_Accept(this, Config); #if defined(MEDIAINFO_REFERENCES_YES) XMLElement* Track=Root->FirstChildElement(); while (Track) { if (string(Track->Value())=="clip") { sequence* Sequence=new sequence; Attribute=Track->Attribute("file"); if (Attribute) { Sequence->AddFileName(Ztring().From_UTF8(Attribute)); Attribute=Track->Attribute("type"); if (Attribute) { Ztring StreamKind; StreamKind.From_UTF8(Attribute); if (StreamKind==__T("video")) Sequence->StreamKind=Stream_Video; if (StreamKind==__T("audio")) Sequence->StreamKind=Stream_Audio; if (StreamKind==__T("data")) Sequence->StreamKind=Stream_Text; //Not sure this is a right mapping, but this is only used when file is missing } Attribute=Track->Attribute("source"); if (Attribute) { Ztring StreamKind; StreamKind.From_UTF8(Attribute); if (StreamKind==__T("main")) Sequence->IsMain=true; } Attribute=Track->Attribute("default_timecode"); if (Attribute) { Sequence->Config["File_DefaultTimeCode"].From_UTF8(Attribute); } Sequence->StreamID=ReferenceFiles->Sequences_Size()+1; } Attribute=Track->Attribute("framerate"); if (Attribute) { Sequence->FrameRate_Set(Ztring().From_UTF8(Attribute).To_float64()); Attribute=Track->Attribute("type"); if (Attribute) { Ztring StreamKind; StreamKind.From_UTF8(Attribute); if (StreamKind==__T("video")) Sequence->StreamKind=Stream_Video; if (StreamKind==__T("audio")) Sequence->StreamKind=Stream_Audio; if (StreamKind==__T("data")) Sequence->StreamKind=Stream_Text; //Not sure this is a right mapping, but this is only used when file is missing } XMLElement* Frame=Track->FirstChildElement(); while (Frame) { if (string(Frame->Value())=="frame") { Attribute=Frame->Attribute("file"); if (Attribute) Sequence->AddFileName(Ztring().From_UTF8(Attribute)); } Frame=Frame->NextSiblingElement(); } } Sequence->StreamID=ReferenceFiles->Sequences_Size()+1; ReferenceFiles->AddSequence(Sequence); } Track=Track->NextSiblingElement(); } #endif //MEDIAINFO_REFERENCES_YES } else { Reject("DXW"); return false; } } Element_Offset=File_Size; //All should be OK... return true; }
//--------------------------------------------------------------------------- bool File_Hls::FileHeader_Begin() { //Element_Size if (File_Size>1024*1024 || File_Size<10) { Reject("HLS"); return false; //HLS files are not big } if (Buffer_Size<File_Size) return false; //Wait for complete file Ztring Document; Document.From_UTF8((char*)Buffer, Buffer_Size); ZtringList Lines; size_t LinesSeparator_Pos=Document.find_first_of(__T("\r\n")); if (LinesSeparator_Pos>File_Size-1) { Reject("HLS"); return false; } Ztring LinesSeparator; if (Document[LinesSeparator_Pos]==__T('\r') && LinesSeparator_Pos+1<Document.size() && Document[LinesSeparator_Pos+1]==__T('\n')) LinesSeparator=__T("\r\n"); else if (Document[LinesSeparator_Pos]==__T('\r')) LinesSeparator=__T("\r"); else if (Document[LinesSeparator_Pos]==__T('\n')) LinesSeparator=__T("\n"); else { Reject("HLS"); return false; } Lines.Separator_Set(0, LinesSeparator); Lines.Write(Document); if (Lines(0)!=__T("#EXTM3U")) { Reject("HLS"); return false; } Accept("HLS"); Fill(Stream_General, 0, General_Format, "HLS"); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); if (!IsSub) ReferenceFiles->ContainerHasNoId=true; File__ReferenceFilesHelper::reference ReferenceFile; bool IsGroup=false; for (size_t Line=0; Line<Lines.size(); Line++) { if (!Lines[Line].empty()) { if (Lines[Line].find(__T("#EXT-X-KEY:"))==0) { ZtringListList List; List.Separator_Set(0, __T(",")); List.Separator_Set(1, __T("=")); List.Write(Lines[Line].substr(11, string::npos)); for (size_t Pos=0; Pos<List.size(); ++Pos) { if (List[Pos](0)==__T("METHOD")) { if (List[Pos](1).find(__T("AES-128"))==0) { Fill(Stream_General, 0, General_Encryption_Format, "AES"); Fill(Stream_General, 0, General_Encryption_Length, "128"); Fill(Stream_General, 0, General_Encryption_Method, "Segment"); Fill(Stream_General, 0, General_Encryption_Mode, "CBC"); Fill(Stream_General, 0, General_Encryption_Padding, "PKCS7"); Fill(Stream_General, 0, General_Encryption_InitializationVector, "Sequence number"); #if MEDIAINFO_AES //Trying to get the key from FileName.FileExt.key if (Config->Encryption_Key_Get().empty()) { File KeyFile; if (KeyFile.Open(File_Name+__T(".key"))) { if (KeyFile.Size_Get()==16) { int8u Key[16]; if (KeyFile.Read(Key, 16)==16) Config->Encryption_Key_Set(Key, 16); } else Fill(Stream_General, 0, "Encryption_Key_Problem", KeyFile.Size_Get()); } } #endif } Fill(Stream_General, 0, General_Encryption, List[Pos](1)); } } } else if (Lines[Line].find(__T("#EXT-X-STREAM-INF:"))==0) { IsGroup=true; } else if (Lines[Line][0]==__T('#')) ; else { if (IsGroup) { ReferenceFile.FileNames.push_back(Lines[Line]); ReferenceFile.StreamID=ReferenceFiles->References.size()+1; ReferenceFiles->References.push_back(ReferenceFile); IsGroup=false; ReferenceFile=File__ReferenceFilesHelper::reference(); #if MEDIAINFO_EVENTS ParserIDs[0]=MediaInfo_Parser_HlsIndex; StreamIDs_Width[0]=sizeof(size_t); #endif //MEDIAINFO_EVENTS } else ReferenceFile.FileNames.push_back(Lines[Line]); } } } if (!ReferenceFile.FileNames.empty()) { ReferenceFiles->References.push_back(ReferenceFile); Fill(Stream_General, 0, General_Format_Profile, "Media"); } else { Fill(Stream_General, 0, General_Format_Profile, "Master"); } Element_Offset=File_Size; //All should be OK... return true; }
//--------------------------------------------------------------------------- void File_Flac::Read_File() { //Init FLAC::Metadata::SimpleIterator SI; if (!SI.is_valid()) return; if (!SI.init(CompleteFileName.To_Local().c_str(), true, true)) return; //Filling Stream_Prepare(Stream_General); Fill("Format", "FLAC"); Stream_Prepare(Stream_Audio); Fill("Codec", "FLAC"); do { switch(SI.get_block_type()) { case FLAC__METADATA_TYPE_STREAMINFO: { FLAC::Metadata::StreamInfo* StreamInfo=(FLAC::Metadata::StreamInfo*)SI.get_block(); if (StreamInfo) { if (StreamInfo->get_min_framesize()==StreamInfo->get_max_framesize() && StreamInfo->get_min_framesize()!=0 ) // 0 means it is unknown Fill("BitRate_Mode", "CBR"); else Fill("BitRate_Mode", "VBR"); Fill("SamplingRate", StreamInfo->get_sample_rate()); Fill("Channel(s)", StreamInfo->get_channels()); Fill("Resolution", StreamInfo->get_bits_per_sample()); Fill(Stream_General, 0, "PlayTime", (int32u)(int64u_float64(StreamInfo->get_total_samples())*1000/StreamInfo->get_sample_rate())); } } break; case FLAC__METADATA_TYPE_PADDING: break; case FLAC__METADATA_TYPE_APPLICATION: break; case FLAC__METADATA_TYPE_SEEKTABLE: break; case FLAC__METADATA_TYPE_VORBIS_COMMENT: { FLAC::Metadata::VorbisComment* vorbiscomment =(FLAC::Metadata::VorbisComment*)SI.get_block(); if (vorbiscomment) { Fill("Encoded_Library", vorbiscomment->get_vendor_string()); for(size_t t=0; t<vorbiscomment->get_num_comments(); t++) { std::string Key(vorbiscomment->get_comment(t).get_field_name(), vorbiscomment->get_comment(t).get_field_name_length()); Ztring Value; Value.From_UTF8(vorbiscomment->get_comment(t).get_field_value(), vorbiscomment->get_comment(t).get_field_value_length()); //Parsing if (Key=="ALBUM") Fill(Stream_General, 0, "Album", Value); else if (Key=="ARTIST") Fill(Stream_General, 0, "Performer", Value); else if (Key=="COPYRIGHT") Fill(Stream_General, 0, "Copyright", Value); else if (Key=="DATE") Fill(Stream_General, 0, "Recorded_Date", Value); else if (Key=="DESCRIPTION") Fill(Stream_General, 0, "Comment", Value); else if (Key=="LOCATION") Fill(Stream_General, 0, "RecordingLocation", Value); else if (Key=="PERFORMER") Fill(Stream_General, 0, "Performer", Value); else if (Key=="TITLE") Fill(Stream_General, 0, "Title", Value); else if (Key=="TRACKNUMBER") Fill(Stream_General, 0, "Track", Value); else Fill(Stream_General, 0, Key.c_str(), Value); } } } break; case FLAC__METADATA_TYPE_CUESHEET: break; }; } while(SI.next()); }
//--------------------------------------------------------------------------- bool File_SubRip::FileHeader_Begin() { if (!IsSub && (Buffer_Size<File_Size && Buffer_Size<65536)) { Element_WaitForMoreData(); return false; } ZtringListList List; List.Separator_Set(0, __T("\n\n")); List.Separator_Set(1, __T("\n")); if (Buffer_Size>=3 && Buffer[0]==0xEF && Buffer[1]==0xBB && Buffer[2]==0xBF) HasBOM=true; bool IsLocal=false; Ztring Temp; Temp.From_UTF8((const char*)Buffer+(HasBOM?3:0), (Buffer_Size>65536?65536:Buffer_Size)-(HasBOM?3:0)); if (Temp.empty()) { #ifdef WINDOWS Temp.From_Local((const char*)Buffer+(HasBOM?3:0), (Buffer_Size>65536?65536:Buffer_Size)-(HasBOM?3:0)); // Trying from local code page #else //WINDOWS Temp.From_ISO_8859_1((const char*)Buffer+(HasBOM?3:0), (Buffer_Size>65536?65536:Buffer_Size)-(HasBOM?3:0)); #endif //WINDOWS IsLocal=true; } Temp.FindAndReplace(__T("\r\n"), __T("\n"), 0, Ztring_Recursive); Temp.FindAndReplace(__T("\r"), __T("\n"), 0, Ztring_Recursive); List.Write(Temp); if (List(0, 0)==__T("WEBVTT FILE") || List(0, 0)==__T("WEBVTT")) IsVTT=true; if (!IsVTT) { size_t IsOk=0; size_t IsNok=0; for (size_t Pos=0; Pos<List.size(); Pos++) { if (List(Pos, 0).To_int64u()==Pos+1) IsOk++; else IsNok++; if (List(Pos, 1).size()>22 && List(Pos, 1)[2]==__T(':') && List(Pos, 1)[5]==__T(':') && List(Pos, 1).find(__T(" --> "))!=string::npos) IsOk++; else IsNok++; } if (!IsOk || IsNok>IsOk/2) { Reject(); return true; } } if (!IsSub && File_Size!=(int64u)-1 && Buffer_Size!=File_Size) { Element_WaitForMoreData(); return false; } if (!Status[IsAccepted]) { Accept(); Fill(Stream_General, 0, General_Format, IsVTT?"WebVTT":"SubRip"); Stream_Prepare(Stream_Text); Fill(Stream_Text, 0, "Format", IsVTT?"WebVTT":"SubRip"); Fill(Stream_Text, 0, "Codec", IsVTT?"WebVTT":"SubRip"); } if (IsLocal) #ifdef WINDOWS Temp.From_Local((const char*)Buffer+(HasBOM?3:0), Buffer_Size-(HasBOM?3:0)); #else //WINDOWS Temp.From_ISO_8859_1((const char*)Buffer+(HasBOM?3:0), Buffer_Size-(HasBOM?3:0)); #endif //WINDOWS else