Пример #1
0
void Representation::localMergeWithPlaylist(M3U8 *updated, mtime_t prunebarrier)
{
    BasePeriod *period = updated->getFirstPeriod();
    if(!period)
        return;

    BaseAdaptationSet *adapt = period->getAdaptationSets().front();
    if(!adapt)
        return;

    BaseRepresentation *rep = adapt->getRepresentations().front();
    if(!rep)
        return;

    this->mergeWith( rep, prunebarrier );
}
Пример #2
0
bool M3U8::isLive() const
{
    std::vector<BasePeriod *>::const_iterator itp;
    for(itp = periods.begin(); itp != periods.end(); ++itp)
    {
        const BasePeriod *period = *itp;
        std::vector<BaseAdaptationSet *>::const_iterator ita;
        for(ita = period->getAdaptationSets().begin(); ita != period->getAdaptationSets().end(); ++ita)
        {
            BaseAdaptationSet *adaptSet = *ita;
            std::vector<BaseRepresentation *>::iterator itr;
            for(itr = adaptSet->getRepresentations().begin(); itr != adaptSet->getRepresentations().end(); ++itr)
            {
                const Representation *rep = dynamic_cast<const Representation *>(*itr);
                if(rep->initialized() && rep->isLive())
                    return true;
            }
        }
    }

    return false;
}
Пример #3
0
bool PlaylistManager::setupPeriod()
{
    if(!currentPeriod)
        return false;

    if(!logic && !(logic = createLogic(logicType, conManager)))
        return false;

    std::vector<BaseAdaptationSet*> sets = currentPeriod->getAdaptationSets();
    std::vector<BaseAdaptationSet*>::iterator it;
    for(it=sets.begin();it!=sets.end();++it)
    {
        BaseAdaptationSet *set = *it;
        if(set && streamFactory)
        {
            SegmentTracker *tracker = new (std::nothrow) SegmentTracker(logic, set);
            if(!tracker)
                continue;

            AbstractStream *st = streamFactory->create(p_demux, set->getStreamFormat(),
                                                       tracker, conManager);
            if(!st)
            {
                delete tracker;
                continue;
            }

            streams.push_back(st);

            /* Generate stream description */
            std::list<std::string> languages;
            if(!set->getLang().empty())
            {
                languages = set->getLang();
            }
            else if(!set->getRepresentations().empty())
            {
                languages = set->getRepresentations().front()->getLang();
            }

            if(!languages.empty())
                st->setLanguage(languages.front());

            if(!set->description.Get().empty())
                st->setDescription(set->description.Get());
        }
    }
    return true;
}
Пример #4
0
M3U8 * M3U8Parser::parse(vlc_object_t *p_object, stream_t *p_stream, const std::string &playlisturl)
{
    char *psz_line = vlc_stream_ReadLine(p_stream);
    if(!psz_line || strcmp(psz_line, "#EXTM3U"))
    {
        free(psz_line);
        return NULL;
    }
    free(psz_line);

    M3U8 *playlist = new (std::nothrow) M3U8(p_object);
    if(!playlist)
        return NULL;

    if(!playlisturl.empty())
        playlist->setPlaylistUrl( Helper::getDirectoryPath(playlisturl).append("/") );

    BasePeriod *period = new (std::nothrow) BasePeriod( playlist );
    if(!period)
        return playlist;

    std::list<Tag *> tagslist = parseEntries(p_stream);
    bool b_masterplaylist = !getTagsFromList(tagslist, AttributesTag::EXTXSTREAMINF).empty();
    if(b_masterplaylist)
    {
        std::list<Tag *>::const_iterator it;
        std::map<std::string, AttributesTag *> groupsmap;

        /* We'll need to create an adaptation set for each media group / alternative rendering
         * we create a list of playlist being and alternative/group */
        std::list<Tag *> mediainfotags = getTagsFromList(tagslist, AttributesTag::EXTXMEDIA);
        for(it = mediainfotags.begin(); it != mediainfotags.end(); ++it)
        {
            AttributesTag *tag = dynamic_cast<AttributesTag *>(*it);
            if(tag && tag->getAttributeByName("URI"))
            {
                std::pair<std::string, AttributesTag *> pair(tag->getAttributeByName("URI")->quotedString(), tag);
                groupsmap.insert(pair);
            }
        }

        /* Then we parse all playlists uri and add them, except when alternative */
        BaseAdaptationSet *adaptSet = new (std::nothrow) BaseAdaptationSet(period);
        if(adaptSet)
        {
            std::list<Tag *> streaminfotags = getTagsFromList(tagslist, AttributesTag::EXTXSTREAMINF);
            for(it = streaminfotags.begin(); it != streaminfotags.end(); ++it)
            {
                AttributesTag *tag = dynamic_cast<AttributesTag *>(*it);
                if(tag && tag->getAttributeByName("URI"))
                {
                    if(groupsmap.find(tag->getAttributeByName("URI")->value) == groupsmap.end())
                    {
                        /* not a group, belong to default adaptation set */
                        Representation *rep  = createRepresentation(adaptSet, tag);
                        if(rep)
                        {
                            adaptSet->addRepresentation(rep);
                        }
                    }
                }
            }
            if(!adaptSet->getRepresentations().empty())
                period->addAdaptationSet(adaptSet);
            else
                delete adaptSet;
        }

        /* Finally add all groups */
        std::map<std::string, AttributesTag *>::const_iterator groupsit;
        for(groupsit = groupsmap.begin(); groupsit != groupsmap.end(); ++groupsit)
        {
            BaseAdaptationSet *altAdaptSet = new (std::nothrow) BaseAdaptationSet(period);
            if(altAdaptSet)
            {
                std::pair<std::string, AttributesTag *> pair = *groupsit;
                Representation *rep  = createRepresentation(altAdaptSet, pair.second);
                if(rep)
                {
                    altAdaptSet->addRepresentation(rep);
                }

                if(pair.second->getAttributeByName("NAME"))
                   altAdaptSet->description.Set(pair.second->getAttributeByName("NAME")->quotedString());

                /* Subtitles unsupported for now */
                if(pair.second->getAttributeByName("TYPE")->value != "AUDIO" &&
                   pair.second->getAttributeByName("TYPE")->value != "VIDEO")
                {
                    rep->streamFormat = StreamFormat(StreamFormat::UNSUPPORTED);
                }

                if(pair.second->getAttributeByName("LANGUAGE"))
                {
                    std::string lang = pair.second->getAttributeByName("LANGUAGE")->quotedString();
                    std::size_t pos = lang.find_first_of('-');
                    if(pos != std::string::npos && pos > 0)
                        altAdaptSet->addLang(lang.substr(0, pos));
                    else if (lang.size() < 4)
                        altAdaptSet->addLang(lang);
                }

                if(!altAdaptSet->getRepresentations().empty())
                    period->addAdaptationSet(altAdaptSet);
                else
                    delete altAdaptSet;
            }
        }

    }
    else /* Non master playlist (opened directly subplaylist or HLS v1) */
    {
        BaseAdaptationSet *adaptSet = new (std::nothrow) BaseAdaptationSet(period);
        if(adaptSet)
        {
            period->addAdaptationSet(adaptSet);
            AttributesTag *tag = new AttributesTag(AttributesTag::EXTXSTREAMINF, "");
            tag->addAttribute(new Attribute("URI", playlisturl));
            createAndFillRepresentation(p_object, adaptSet, tag, tagslist);
            delete tag;
        }
    }

    playlist->addPeriod(period);

    releaseTagsList(tagslist);

    playlist->debug();
    return playlist;
}