vlc_player.cpp 4.89 KB
Newer Older
1
/*****************************************************************************
2
 * Copyright � 2002-2011 VideoLAN and VLC authors
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * $Id$
 *
 * Authors: Sergey Radionov <rsatom_gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

22 23 24 25
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

26 27 28 29 30 31
#if defined(_WIN32)
#  include <windows.h>
#else
#  include <future>
#endif

32 33
#include "vlc_player.h"

34
bool vlc_player::open(VLC::Instance& inst)
35 36 37 38 39 40
{
    if( !inst )
        return false;

    _libvlc_instance = inst;

41 42 43 44
    try {
        _mp   = VLC::MediaPlayer(inst);
        _ml   = VLC::MediaList(inst);
        _ml_p = VLC::MediaListPlayer(inst);
45

46 47
        _ml_p.setMediaList( _ml );
        _ml_p.setMediaPlayer( _mp );
48
    }
49
    catch (std::runtime_error&) {
50 51 52 53 54 55 56 57
        return false;
    }

    return true;
}

int vlc_player::add_item(const char * mrl, unsigned int optc, const char **optv)
{
58 59 60 61 62
    VLC::Media media;
    try {
        media = VLC::Media( _libvlc_instance, mrl, VLC::Media::FromLocation );
    }
    catch ( std::runtime_error& ) {
63
        return -1;
64
    }
65 66

    for( unsigned int i = 0; i < optc; ++i )
67
        media.addOptionFlag( optv[i], libvlc_media_option_unique );
68

69 70 71 72
    VLC::MediaList::Lock lock( _ml );
    if( _ml.addMedia( media ) )
         return _ml.count() - 1;
    return -1;
73 74 75 76
}

int vlc_player::current_item()
{
77
    auto media = _mp.media();
78 79 80

    if( !media )
        return -1;
81
    return _ml.indexOfItem( *media );
82 83 84 85
}

int vlc_player::items_count()
{
86 87
    VLC::MediaList::Lock lock( _ml );
    return _ml.count();
88 89 90 91
}

bool vlc_player::delete_item(unsigned int idx)
{
92 93
    VLC::MediaList::Lock lock( _ml );
    return _ml.removeIndex( idx );
94 95 96 97
}

void vlc_player::clear_items()
{
98 99 100
    VLC::MediaList::Lock lock( _ml );
    for( int i = _ml.count(); i > 0; --i) {
        _ml.removeIndex( i - 1 );
101 102 103
    }
}

104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
int vlc_player::preparse_item_sync(unsigned int idx, int options, unsigned int timeout)
{
    int retval = -1;

    VLC::MediaList::Lock lock( _ml );
    auto media = _ml.itemAtIndex( idx );
    if ( !media )
        return -1;
    auto em = media->eventManager();

#  if defined(_WIN32)
    HANDLE barrier = CreateEvent(nullptr, true,  false, nullptr);
    if ( barrier == nullptr )
        return -1;

    auto event = em.onParsedChanged(
        [&barrier, &retval](VLC::Media::ParsedStatus status )
    {
        retval = int( status );
        SetEvent( barrier );
    });

    media->parseWithOptions( VLC::Media::ParseFlags( options ), timeout );

    DWORD waitResult = WaitForSingleObject( barrier, INFINITE );
    switch ( waitResult ) {
    case WAIT_OBJECT_0:
        break;
    default:
        retval = -1;
        break;
    }
    CloseHandle( barrier );
    event->unregister();
#  else
    std::promise<int> promise;
    std::future<int> future = promise.get_future();

    auto event = em.onParsedChanged(
        [&promise]( VLC::Media::ParsedStatus status )
    {
        promise.set_value( int( status ) );
    });

    media->parseWithOptions( VLC::Media::ParseFlags( options ), timeout );

    future.wait();
    retval = future.get();
    event->unregister();
#  endif

    return retval;
}

std::shared_ptr<VLC::Media> vlc_player::get_media(unsigned int idx)
{
    return _ml.itemAtIndex(idx);
}

163 164
void vlc_player::play()
{
165 166 167
    if( 0 == items_count() )
        return;
    else if( -1 == current_item() ) {
168
        _ml_p.playItemAtIndex( 0 );
169
    }
170
    else
171
        _ml_p.play();
172
}
173 174 175

int vlc_player::currentAudioTrack()
{
176 177
    auto current = _mp.audioTrack();
    auto tracks = _mp.audioTrackDescription();
178 179 180 181 182 183 184 185 186 187
    return getTrack( current, tracks );
}

int vlc_player::currentSubtitleTrack()
{
    auto current = _mp.spu();
    auto tracks = _mp.spuDescription();
    return getTrack( current, tracks );
}

188 189 190 191 192 193 194
int vlc_player::currentVideoTrack()
{
    auto current = _mp.videoTrack();
    auto tracks = _mp.videoTrackDescription();
    return getTrack( current, tracks );
}

195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
int vlc_player::getTrack( int currentId, const std::vector<VLC::TrackDescription>& tracks )
{
    if ( tracks.empty() )
        return -1;

    int trackId = 0;
    for ( const auto& t : tracks )
    {
        if ( t.id() == currentId )
        {
            return trackId;
        }
        ++trackId;
    }
    return -1;
}