bool CDVDSubtitleParserVplayer::Open(CDVDStreamInfo &hints) { if (!CDVDSubtitleParserText::Open()) return false; // Vplayer subtitles have 1-second resolution m_framerate = DVD_TIME_BASE; // Vplayer subtitles don't have StopTime, so we use following subtitle's StartTime // for that, unless gap was more than 4 seconds. Then we set subtitle duration // for 4 seconds, to not have text hanging around in silent scenes... int iDefaultDuration = 4 * (int)m_framerate; char line[1024]; CRegExp reg; if (!reg.RegComp("([0-9]+):([0-9]+):([0-9]+):([^|]*?)(\\|([^|]*?))?$")) return false; CDVDOverlayText* pPrevOverlay = NULL; while (m_pStream->ReadLine(line, sizeof(line))) { if (reg.RegFind(line) > -1) { std::string hour(reg.GetMatch(1)); std::string min (reg.GetMatch(2)); std::string sec (reg.GetMatch(3)); std::string lines[3]; lines[0] = reg.GetMatch(4); lines[1] = reg.GetMatch(6); lines[2] = reg.GetMatch(8); CDVDOverlayText* pOverlay = new CDVDOverlayText(); pOverlay->Acquire(); // increase ref count with one so that we can hold a handle to this overlay pOverlay->iPTSStartTime = m_framerate * (3600*atoi(hour.c_str()) + 60*atoi(min.c_str()) + atoi(sec.c_str())); // set StopTime for previous overlay if (pPrevOverlay) { if ( (pOverlay->iPTSStartTime - pPrevOverlay->iPTSStartTime) < iDefaultDuration) pPrevOverlay->iPTSStopTime = pOverlay->iPTSStartTime; else pPrevOverlay->iPTSStopTime = pPrevOverlay->iPTSStartTime + iDefaultDuration; } pPrevOverlay = pOverlay; for (int i = 0; i < 3 && !lines[i].empty(); i++) pOverlay->AddElement(new CDVDOverlayText::CElementText(lines[i].c_str())); m_collection.Add(pOverlay); } // set StopTime for the last subtitle if (pPrevOverlay) pPrevOverlay->iPTSStopTime = pPrevOverlay->iPTSStartTime + iDefaultDuration; } return true; }
int CDVDSubtitleParserSubrip::ParseFile() { char line[1024]; char* pLineStart; while (m_pStream->ReadLine(line, sizeof(line))) { pLineStart = line; // trim while (pLineStart[0] == ' ') pLineStart++; if (strlen(pLineStart) > 0) { char sep; int hh1, mm1, ss1, ms1, hh2, mm2, ss2, ms2; int c = sscanf(line, "%d%c%d%c%d%c%d --> %d%c%d%c%d%c%d\n", &hh1, &sep, &mm1, &sep, &ss1, &sep, &ms1, &hh2, &sep, &mm2, &sep, &ss2, &sep, &ms2); if (c == 1) { // numbering, skip it } else if (c == 14) // time info { CDVDOverlayText* pOverlay = new CDVDOverlayText(); pOverlay->Acquire(); // increase ref count with one so that we can hold a handle to this overlay pOverlay->iPTSStartTime = ((double)(((hh1 * 60 + mm1) * 60) + ss1) * 1000 + ms1) * (DVD_TIME_BASE / 1000); pOverlay->iPTSStopTime = ((double)(((hh2 * 60 + mm2) * 60) + ss2) * 1000 + ms2) * (DVD_TIME_BASE / 1000); while (m_pStream->ReadLine(line, sizeof(line))) { pLineStart = line; // trim while (pLineStart[0] == ' ') pLineStart++; // empty line, next subtitle is about to start if (strlen(pLineStart) <= 0) break; CStdStringW strUTF16; CStdStringA strUTF8; g_charsetConverter.subtitleCharsetToW(pLineStart, strUTF16); g_charsetConverter.wToUTF8(strUTF16, strUTF8); // add a new text element to our container pOverlay->AddElement(new CDVDOverlayText::CElementText(strUTF8.c_str())); } m_collection.Add(pOverlay); } } } return m_collection.GetSize(); }
bool CDVDSubtitleParserSubrip::Open(CDVDStreamInfo &hints) { if (!CDVDSubtitleParserText::Open()) return false; CDVDSubtitleTagSami TagConv; if (!TagConv.Init()) return false; char line[1024]; CStdString strLine; while (m_pStream->ReadLine(line, sizeof(line))) { strLine = line; strLine.Trim(); if (strLine.length() > 0) { char sep; int hh1, mm1, ss1, ms1, hh2, mm2, ss2, ms2; int c = sscanf(strLine.c_str(), "%d%c%d%c%d%c%d --> %d%c%d%c%d%c%d\n", &hh1, &sep, &mm1, &sep, &ss1, &sep, &ms1, &hh2, &sep, &mm2, &sep, &ss2, &sep, &ms2); if (c == 1) { // numbering, skip it } else if (c == 14) // time info { CDVDOverlayText* pOverlay = new CDVDOverlayText(); pOverlay->Acquire(); // increase ref count with one so that we can hold a handle to this overlay pOverlay->iPTSStartTime = ((double)(((hh1 * 60 + mm1) * 60) + ss1) * 1000 + ms1) * (DVD_TIME_BASE / 1000); pOverlay->iPTSStopTime = ((double)(((hh2 * 60 + mm2) * 60) + ss2) * 1000 + ms2) * (DVD_TIME_BASE / 1000); while (m_pStream->ReadLine(line, sizeof(line))) { strLine = line; strLine.Trim(); // empty line, next subtitle is about to start if (strLine.length() <= 0) break; TagConv.ConvertLine(pOverlay, strLine.c_str(), strLine.length()); } TagConv.CloseTag(pOverlay); m_collection.Add(pOverlay); } } } m_collection.Sort(); return true; }
bool CDVDSubtitleParserSami::Open(CDVDStreamInfo &hints) { if (!m_pStream->Open(m_strFileName)) return false; char line[1024]; char text[1024]; CRegExp reg; if (!reg.RegComp("<SYNC START=([0-9]+)>")) assert(0); bool reuse=false; while (reuse || m_pStream->ReadLine(line, sizeof(line))) { if (reg.RegFind(line) > -1) { char* startFrame = reg.GetReplaceString("\\1"); m_pStream->ReadLine(text,sizeof(text)); m_pStream->ReadLine(line,sizeof(line)); if (reg.RegFind(line) > -1) { char* endFrame = reg.GetReplaceString("\\1"); CDVDOverlayText* pOverlay = new CDVDOverlayText(); pOverlay->Acquire(); // increase ref count with one so that we can hold a handle to this overlay pOverlay->iPTSStartTime = atoi(startFrame)*DVD_TIME_BASE/1000; pOverlay->iPTSStopTime = atoi(endFrame)*DVD_TIME_BASE/1000; CStdStringW strUTF16; CStdStringA strUTF8; g_charsetConverter.subtitleCharsetToW(text, strUTF16); g_charsetConverter.wToUTF8(strUTF16, strUTF8); if (strUTF8.IsEmpty()) continue; // add a new text element to our container pOverlay->AddElement(new CDVDOverlayText::CElementText(strUTF8.c_str())); reuse = true; free(endFrame); m_collection.Add(pOverlay); } free(startFrame); } else reuse = false; } return true; }
bool CDVDSubtitleParserMicroDVD::Open(CDVDStreamInfo &hints) { if (!CDVDSubtitleParserText::Open()) return false; CLog::Log(LOGDEBUG, "%s - framerate %d:%d", __FUNCTION__, hints.fpsrate, hints.fpsscale); if (hints.fpsscale > 0 && hints.fpsrate > 0) { m_framerate = (double)hints.fpsscale / (double)hints.fpsrate; m_framerate *= DVD_TIME_BASE; } else m_framerate = DVD_TIME_BASE / 25.0; char line[1024]; CRegExp reg; if (!reg.RegComp("\\{([0-9]+)\\}\\{([0-9]+)\\}")) return false; CDVDSubtitleTagMicroDVD TagConv; while (m_pStream->ReadLine(line, sizeof(line))) { if ((strlen(line) > 0) && (line[strlen(line) - 1] == '\r')) line[strlen(line) - 1] = 0; int pos = reg.RegFind(line); if (pos > -1) { const char* text = line + pos + reg.GetFindLen(); std::string startFrame = reg.GetReplaceString("\\1"); std::string endFrame = reg.GetReplaceString("\\2"); CDVDOverlayText* pOverlay = new CDVDOverlayText(); pOverlay->Acquire(); // increase ref count with one so that we can hold a handle to this overlay pOverlay->iPTSStartTime = m_framerate * atoi(startFrame.c_str()); pOverlay->iPTSStopTime = m_framerate * atoi(endFrame.c_str()); TagConv.ConvertLine(pOverlay, text, strlen(text)); m_collection.Add(pOverlay); } } return true; }
bool CDVDSubtitleParserMPL2::Open(CDVDStreamInfo &hints) { if (!CDVDSubtitleParserText::Open()) return false; // MPL2 is time-based, with 0.1s accuracy m_framerate = DVD_TIME_BASE / 10.0; char line[1024]; CRegExp reg; if (!reg.RegComp("\\[([0-9]+)\\]\\[([0-9]+)\\]")) return false; CDVDSubtitleTagMicroDVD TagConv; while (m_pStream->ReadLine(line, sizeof(line))) { if ((strlen(line) > 0) && (line[strlen(line) - 1] == '\r')) line[strlen(line) - 1] = 0; int pos = reg.RegFind(line); if (pos > -1) { const char* text = line + pos + reg.GetFindLen(); char* startFrame = reg.GetReplaceString("\\1"); char* endFrame = reg.GetReplaceString("\\2"); CDVDOverlayText* pOverlay = new CDVDOverlayText(); pOverlay->Acquire(); // increase ref count with one so that we can hold a handle to this overlay pOverlay->iPTSStartTime = m_framerate * atoi(startFrame); pOverlay->iPTSStopTime = m_framerate * atoi(endFrame); TagConv.ConvertLine(pOverlay, text, strlen(text)); free(startFrame); free(endFrame); m_collection.Add(pOverlay); } } return true; }
bool CDVDSubtitleParserSami::Open(CDVDStreamInfo &hints) { if (!CDVDSubtitleParserText::Open()) return false; char line[1024]; CRegExp reg(true); if (!reg.RegComp("<SYNC START=([0-9]+)>")) return false; CStdString strFileName; CStdString strClassID; strFileName = CUtil::GetFileName(m_filename); CDVDSubtitleTagSami TagConv; if (!TagConv.Init()) return false; TagConv.LoadHead(m_pStream); if (TagConv.m_Langclass.size() >= 2) { for (unsigned int i = 0; i < TagConv.m_Langclass.size(); i++) { if (strFileName.Find(TagConv.m_Langclass[i].Name, 9) == 9) { strClassID = TagConv.m_Langclass[i].ID.ToLower(); break; } } } const char *lang = NULL; if (!strClassID.IsEmpty()) lang = strClassID.c_str(); CDVDOverlayText* pOverlay = NULL; while (m_pStream->ReadLine(line, sizeof(line))) { if ((strlen(line) > 0) && (line[strlen(line) - 1] == '\r')) line[strlen(line) - 1] = 0; int pos = reg.RegFind(line); const char* text = line; if (pos > -1) { CStdString start = reg.GetMatch(1); if(pOverlay) { TagConv.ConvertLine(pOverlay, text, pos, lang); pOverlay->iPTSStopTime = (double)atoi(start.c_str()) * DVD_TIME_BASE / 1000; pOverlay->Release(); TagConv.CloseTag(pOverlay); } pOverlay = new CDVDOverlayText(); pOverlay->Acquire(); // increase ref count with one so that we can hold a handle to this overlay pOverlay->iPTSStartTime = (double)atoi(start.c_str()) * DVD_TIME_BASE / 1000; pOverlay->iPTSStopTime = DVD_NOPTS_VALUE; m_collection.Add(pOverlay); text += pos + reg.GetFindLen(); } if(pOverlay) TagConv.ConvertLine(pOverlay, text, strlen(text), lang); } m_collection.Sort(); return true; }