Media.hpp 13.4 KB
Newer Older
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
1 2 3 4 5 6
/*****************************************************************************
 * libvlc_Media.hpp: Media API
 *****************************************************************************
 * Copyright © 2014 the VideoLAN team
 *
 * Authors: Alexey Sokolov <alexey@alexeysokolov.co.cc>
7
 *          Hugo Beauzée-Luyssen <hugo@beauzee.fr>
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 *
 * 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.
 *****************************************************************************/

#ifndef LIBVLC_CXX_MEDIA_H
#define LIBVLC_CXX_MEDIA_H

27 28
#include "common.hpp"

29
#include <vector>
30
#include <stdexcept>
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
31

32
namespace VLC
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
33 34
{

Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
35
class MediaPlayer;
36
class EventManager;
37 38
class Instance;
class MediaList;
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
39

40
class VLCPP_API Media : public Internal<libvlc_media_t>
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
41 42
{
public:
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64

    enum FromType
    {
        /**
         * Create a media for a certain file path.
         */
        FromPath,
        /**
         * Create a media with a certain given media resource location,
         * for instance a valid URL.
         *
         * \note To refer to a local file with this function,
         * the file://... URI syntax <b>must</b> be used (see IETF RFC3986).
         * We recommend using FromPath instead when dealing with
         * local files.
         */
        FromLocation,
        /**
         * Create a media as an empty node with a given name.
         */
        AsNode,
    };
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
65 66

    /**
67 68 69 70
     * @brief Media Constructs a libvlc Media instance
     * @param instance  A libvlc instance
     * @param mrl       A path, location, or node name, depending on the 3rd parameter
     * @param type      The type of the 2nd argument. \sa{FromType}
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
71
     */
72
    Media(Instance& instance, const std::string& mrl, FromType type)
73 74 75 76 77 78
        : Internal{ libvlc_media_release }
    {
        InternalPtr ptr = nullptr;
        switch (type)
        {
        case FromLocation:
79
            ptr = libvlc_media_new_location( getInternalPtr<libvlc_instance_t>( instance ), mrl.c_str() );
80 81
            break;
        case FromPath:
82
            ptr = libvlc_media_new_path( getInternalPtr<libvlc_instance_t>( instance ), mrl.c_str() );
83 84
            break;
        case AsNode:
85
            ptr = libvlc_media_new_as_node( getInternalPtr<libvlc_instance_t>( instance ), mrl.c_str() );
86 87 88 89 90 91
            break;
        default:
            break;
        }
        if ( ptr == nullptr )
            throw std::runtime_error("Failed to construct a media");
92
        m_obj.reset( ptr, libvlc_media_release );
93
    }
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
94 95

    /**
96 97
     * Create a media for an already open file descriptor.
     * The file descriptor shall be open for reading (or reading and writing).
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
98 99
     *
     * Regular file descriptors, pipe read descriptors and character device
100 101 102 103 104 105 106 107
     * descriptors (including TTYs) are supported on all platforms.
     * Block device descriptors are supported where available.
     * Directory descriptors are supported on systems that provide fdopendir().
     * Sockets are supported on all platforms where they are file descriptors,
     * i.e. all except Windows.
     *
     * \note This library will <b>not</b> automatically close the file descriptor
     * under any circumstance. Nevertheless, a file descriptor can usually only be
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
108 109 110
     * rendered once in a media player. To render it a second time, the file
     * descriptor should probably be rewound to the beginning with lseek().
     *
111 112 113 114
     * \param p_instance the instance
     * \param fd open file descriptor
     * \return the newly created media or NULL on error
     */
115 116 117
    Media(Instance& instance, int fd)
        : Internal { libvlc_media_new_fd( getInternalPtr<libvlc_instance_t>( instance ), fd ),
                     libvlc_media_release }
118 119
    {
    }
120 121 122 123 124

    /**
     * Get media instance from this media list instance. This action will increase
     * the refcount on the media instance.
     * The libvlc_media_list_lock should NOT be held upon entering this function.
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
125
     *
126 127
     * \param p_ml a media list instance
     * \return media instance
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
128
     */
129
    Media(MediaList& list)
130 131 132 133
        : Internal{ libvlc_media_list_media( getInternalPtr<libvlc_media_list_t>( list ) ),
                    libvlc_media_release }
    {
    }
134

135
    explicit Media( Internal::InternalPtr ptr, bool incrementRefCount)
136 137 138 139 140
        : Internal{ ptr, libvlc_media_release }
    {
        if (incrementRefCount)
            retain();
    }
141 142 143 144 145 146

    /**
     * Check if 2 Media objects contain the same libvlc_media_t.
     * \param another another Media
     * \return true if they contain the same libvlc_media_t
     */
147 148 149 150
    bool operator==(const Media& another) const
    {
        return m_obj == another.m_obj;
    }
151

Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
    /**
     * Add an option to the media.
     *
     * This option will be used to determine how the media_player will read
     * the media. This allows to use VLC's advanced reading/streaming options
     * on a per-media basis.
     *
     * \note The options are listed in 'vlc long-help' from the command line,
     * e.g. "-sout-all". Keep in mind that available options and their
     * semantics vary across LibVLC versions and builds.
     *
     * \warning Not all options affects libvlc_media_t objects: Specifically,
     * due to architectural issues most audio and video options, such as text
     * renderer options, have no effects on an individual media. These
     * options must be set through Instance::Instance() instead.
     *
     * \param psz_options  the options (as a string)
     */
170 171
    void addOption(const std::string& psz_options)
    {
172
        libvlc_media_add_option(*this,psz_options.c_str());
173
    }
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191

    /**
     * Add an option to the media with configurable flags.
     *
     * This option will be used to determine how the media_player will read
     * the media. This allows to use VLC's advanced reading/streaming options
     * on a per-media basis.
     *
     * The options are detailed in vlc long-help, for instance "--sout-all".
     * Note that all options are not usable on medias: specifically, due to
     * architectural issues, video-related options such as text renderer
     * options cannot be set on a single media. They must be set on the whole
     * libvlc instance instead.
     *
     * \param psz_options  the options (as a string)
     *
     * \param i_flags  the flags for this option
     */
192 193
    void addOptionFlag(const std::string& psz_options, unsigned i_flags)
    {
194
        libvlc_media_add_option_flag(*this,psz_options.c_str(), i_flags);
195
    }
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
196 197 198 199 200 201

    /**
     * Get the media resource locator (mrl) from a media descriptor object
     *
     * \return string with mrl of media descriptor object
     */
202 203
    std::string mrl()
    {
204
        char* c_result = libvlc_media_get_mrl(*this);
205 206 207 208 209 210
        if ( c_result == NULL )
            return std::string();
        std::string result = c_result;
        libvlc_free(c_result);
        return result;
    }
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
211 212 213 214

    /**
     * Duplicate a media descriptor object.
     */
215 216
    MediaPtr duplicate()
    {
217
        auto obj = libvlc_media_duplicate(*this);
218 219
        return std::make_shared<Media>( obj, false );
    }
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
220 221 222 223 224 225

    /**
     * Read the meta of the media.
     *
     * If the media has not yet been parsed this will return NULL.
     *
226
     * This methods automatically calls parseAsync() , so after
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
227
     * calling it you may receive a libvlc_MediaMetaChanged event. If you
228
     * prefer a synchronous version ensure that you call parse()
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
229 230
     * before get_meta().
     *
231
     * \see parse()
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
232
     *
233
     * \see parseAsync()
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
234 235 236 237 238 239 240
     *
     * \see libvlc_MediaMetaChanged
     *
     * \param e_meta  the meta to read
     *
     * \return the media's meta
     */
241 242
    std::string meta(libvlc_meta_t e_meta)
    {
243
        char* c_result = libvlc_media_get_meta(*this, e_meta);
244 245 246 247 248 249
        if ( c_result == NULL )
            return std::string();
        std::string result = c_result;
        libvlc_free(c_result);
        return result;
    }
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
250 251 252 253 254 255 256 257 258

    /**
     * Set the meta of the media (this function will not save the meta, call
     * libvlc_media_save_meta in order to save the meta)
     *
     * \param e_meta  the meta to write
     *
     * \param psz_value  the media's meta
     */
259 260
    void setMeta(libvlc_meta_t e_meta, const std::string& psz_value)
    {
261
        libvlc_media_set_meta(*this, e_meta, psz_value.c_str());
262 263
    }

Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
264 265 266 267 268 269

    /**
     * Save the meta previously set
     *
     * \return true if the write operation was successful
     */
270 271
    int saveMeta()
    {
272
        return libvlc_media_save_meta(*this);
273
    }
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
274 275 276 277 278 279 280 281 282 283 284

    /**
     * Get current state of media descriptor object. Possible media states
     * are defined in libvlc_structures.c ( libvlc_NothingSpecial=0,
     * libvlc_Opening, libvlc_Buffering, libvlc_Playing, libvlc_Paused,
     * libvlc_Stopped, libvlc_Ended, libvlc_Error).
     *
     * \see libvlc_state_t
     *
     * \return state of media descriptor object
     */
285 286
    libvlc_state_t state()
    {
287
        return libvlc_media_get_state(*this);
288
    }
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
289 290 291 292 293 294 295 296 297

    /**
     * Get the current statistics about the media
     *
     * \param p_stats  structure that contain the statistics about the media
     * (this structure must be allocated by the caller)
     *
     * \return true if the statistics are available, false otherwise
     */
298 299
    bool stats(libvlc_media_stats_t * p_stats)
    {
300
        return libvlc_media_get_stats(*this,p_stats);
301
    }
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
302 303 304 305 306 307 308

    /**
     * Get event manager from media descriptor object. NOTE: this function
     * doesn't increment reference counting.
     *
     * \return event manager object
     */
309 310 311 312
    EventManagerPtr eventManager()
    {
        if ( m_eventManager == NULL )
        {
313
            libvlc_event_manager_t* obj = libvlc_media_event_manager(*this);
314 315 316 317
            m_eventManager = std::make_shared<EventManager>( obj );
        }
        return m_eventManager;
    }
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
318 319 320 321 322 323

    /**
     * Get duration (in ms) of media descriptor object item.
     *
     * \return duration of media item or -1 on error
     */
324 325
    libvlc_time_t duration()
    {
326
        return libvlc_media_get_duration(*this);
327
    }
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
328 329 330 331 332 333 334

    /**
     * Parse a media.
     *
     * This fetches (local) meta data and tracks information. The method is
     * synchronous.
     *
335
     * \see parseAsync()
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
336
     *
337
     * \see meta()
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
338
     *
339
     * \see tracksInfo()
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
340
     */
341 342
    void parse()
    {
343
        libvlc_media_parse(*this);
344
    }
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
345 346 347 348 349

    /**
     * Parse a media.
     *
     * This fetches (local) meta data and tracks information. The method is
350
     * the asynchronous of parse() .
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
351 352 353 354 355
     *
     * To track when this is over you can listen to libvlc_MediaParsedChanged
     * event. However if the media was already parsed you will not receive
     * this event.
     *
356
     * \see parse()
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
357 358 359
     *
     * \see libvlc_MediaParsedChanged
     *
360
     * \see meta()
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
361
     *
362
     * \see tracks()
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
363
     */
364 365
    void parseAsync()
    {
366
        libvlc_media_parse_async(*this);
367
    }
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
368 369 370 371 372 373 374 375 376

    /**
     * Get Parsed status for media descriptor object.
     *
     * \see libvlc_MediaParsedChanged
     *
     * \return true if media object has been parsed otherwise it returns
     * false
     */
377 378
    bool isParsed()
    {
379
        return libvlc_media_is_parsed(*this);
380
    }
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
381 382 383 384 385 386 387 388

    /**
     * Sets media descriptor's user_data. user_data is specialized data
     * accessed by the host application, VLC.framework uses it as a pointer
     * to an native object that references a libvlc_media_t pointer
     *
     * \param p_new_user_data  pointer to user data
     */
389 390
    void setUserData(void * p_new_user_data)
    {
391
        libvlc_media_set_user_data(*this, p_new_user_data);
392
    }
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
393 394 395 396 397 398

    /**
     * Get media descriptor's user_data. user_data is specialized data
     * accessed by the host application, VLC.framework uses it as a pointer
     * to an native object that references a libvlc_media_t pointer
     */
399 400
    void* userData()
    {
401
        return libvlc_media_get_user_data(*this);
402
    }
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
403 404 405 406

    /**
     * Get media descriptor's elementary streams description
     *
407
     * Note, you need to call parse() or play the media at least once
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
408 409 410 411 412
     * before calling this function. Not doing this will result in an empty
     * array.
     *
     * \version LibVLC 2.1.0 and later.
     *
413
     * \return a vector containing all tracks
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
414
     */
415 416 417
    std::vector<MediaTrack> tracks()
    {
        libvlc_media_track_t**  tracks;
418
        uint32_t                nbTracks = libvlc_media_tracks_get(*this, &tracks);
419 420 421 422 423 424 425 426 427 428
        std::vector<MediaTrack> res;

        if ( nbTracks == 0 )
            return res;

        for ( uint32_t i = 0; i < nbTracks; ++i )
            res.push_back( MediaTrack(tracks[i]));
        libvlc_media_tracks_release( tracks, nbTracks );
        return res;
    }
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
429 430

private:
431

Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
432 433
    /**
     * Retain a reference to a media descriptor object (libvlc_media_t). Use
434
     * release() to decrement the reference count of a media
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
435 436
     * descriptor object.
     */
437 438 439
    void retain()
    {
        if ( isValid() )
440
            libvlc_media_retain(*this);
441
    }
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
442

Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
443

444
private:
445
    EventManagerPtr m_eventManager;
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
446 447 448 449 450 451
};

} // namespace VLC

#endif