Example #1
0
void MFPlayerControl::handleSeekableUpdate(bool seekable)
{
    if (m_seekable == seekable)
        return;
    m_seekable = seekable;
    emit seekableChanged(m_seekable);
}
void QGstreamerPlayerSession::setSeekable(bool seekable)
{
    if (seekable != m_seekable) {
        m_seekable = seekable;
        emit seekableChanged(m_seekable);
    }
}
void DirectShowPlayerControl::emitPropertyChanges()
{
    int properties = m_updateProperties;
    m_updateProperties = 0;

    if ((properties & ErrorProperty) && m_error != QMediaPlayer::NoError)
        emit error(m_error, m_errorString);

    if (properties & PlaybackRateProperty)
        emit playbackRateChanged(m_playbackRate);

    if (properties & StreamTypesProperty) {
        emit audioAvailableChanged(m_streamTypes & DirectShowPlayerService::AudioStream);
        emit videoAvailableChanged(m_streamTypes & DirectShowPlayerService::VideoStream);
    }

    if (properties & PositionProperty)
        emit positionChanged(m_position);

    if (properties & DurationProperty)
        emit durationChanged(m_duration);

    if (properties & SeekableProperty)
        emit seekableChanged(m_seekable);

    if (properties & StatusProperty)
        emit mediaStatusChanged(m_status);

    if (properties & StateProperty)
        emit stateChanged(m_state);
}
void QAndroidPlayerSession::setSeekable(bool seekable)
{
    if (seekable != m_seekable) {
        m_seekable = seekable;
        emit seekableChanged(m_seekable);
    }
}
void QAndroidMediaPlayerControl::setSeekable(bool seekable)
{
    if (mSeekable == seekable)
        return;

    mSeekable = seekable;
    Q_EMIT seekableChanged(mSeekable);
}
void MmRendererMediaPlayerControl::updateMetaData()
{
    if (m_mediaStatus == QMediaPlayer::LoadedMedia)
        m_metaData.parse(m_contextName);
    else
        m_metaData.clear();

    if (m_videoWindowControl)
        m_videoWindowControl->setMetaData(m_metaData);

    if (m_metaDataReaderControl)
        m_metaDataReaderControl->setMetaData(m_metaData);

    emit durationChanged(m_metaData.duration());
    emit audioAvailableChanged(m_metaData.hasAudio());
    emit videoAvailableChanged(m_metaData.hasVideo());
    emit availablePlaybackRangesChanged(availablePlaybackRanges());
    emit seekableChanged(m_metaData.isSeekable());
}
 void setSeekable(bool seekable) { emit seekableChanged(m_seekable = seekable); }
Example #8
0
void VlcQmlVideoPlayer::seekableChangedPrivate(bool seekable)
{
    _seekable = seekable;
    emit seekableChanged();
}
Example #9
0
void MPlayerProcess::parseLine(const QString & tmp) {
	QString line = tmp;

	//Skip empty lines
	if (line.isEmpty()) {
		return;
	}

	//Skip repeatitive lines
	if (line.contains("Too many buffered pts") || line.contains("pts value <= previous")) {
		return;
	}

	//Parse A: V: line
	if (rx_av.indexIn(line) > -1) {
		_mediaData.currentTime = (qint64) (rx_av.cap(1).toDouble() * SECONDS_CONVERTION);

		if (_currentState != Phonon::PlayingState) {
			qDebug() << __FUNCTION__ << "Starting time:" << _mediaData.currentTime;
			changeState(Phonon::PlayingState);

			//OK, now all the media datas should be in clean state
			emit mediaLoaded();
		}

		emit tick(_mediaData.currentTime);

		//Check for frame number
		if (rx_frame.indexIn(line) > -1) {
			int frame = rx_frame.cap(1).toInt();
			//qDebug() << __FUNCTION__ << "Frame number:" << frame;
			emit currentFrameNumberReceived(frame);
		}
	}

	//Parse other things
	else {
		qDebug() << "MPlayer:" << line;

		//Loading the file/stream/media
		//Becarefull! "Playing" does not mean the file is playing but only loading
		if (rx_playing.indexIn(line) > -1) {
			changeState(Phonon::LoadingState);
		}

		//File not found
		else if (rx_file_not_found.indexIn(line) > -1) {
			_errorString = "File not found";
			_errorType = Phonon::NormalError;
			changeState(Phonon::ErrorState);
		}

		//Screenshot
		else if (rx_screenshot.indexIn(line) > -1) {
			const QString filename = rx_screenshot.cap(1);
			qDebug() << __FUNCTION__ << "Screenshot:" << filename;
			emit screenshotSaved(filename);
		}

		//End of file
		else if (rx_endoffile.indexIn(line) > -1) {
			qDebug() << __FUNCTION__ << "End of file detected";

			//In case of playing VCDs or DVDs, maybe the first title
			//is not playable, so the GUI doesn't get the info about
			//available titles. So if we received the end of file
			//first let's pretend the file has started so the GUI can have
			//the data.
			if (_currentState != Phonon::PlayingState) {
				changeState(Phonon::PlayingState);
			}

			//Sends the endOfFileReached() signal once the process is finished, not now!
			_endOfFileReached = true;
		}

		//Window resolution
		else if (rx_winresolution.indexIn(line) > -1) {
			int width = rx_winresolution.cap(4).toInt();
			int height = rx_winresolution.cap(5).toInt();

			qDebug() << __FUNCTION__ << "Video driver:" << rx_winresolution.cap(1);

			//Now we know the real video size
			emit videoWidgetSizeChanged(width, height);

			//Ok, now we can be in PlayingState if we have a video stream
			//If we have only an audio stream, we are already in PlayingState
			changeState(Phonon::PlayingState);

			//emit mplayerFullyLoaded();
		}

		//No video
		else if (rx_novideo.indexIn(line) > -1) {
			_mediaData.hasVideo = false;
			qDebug() << __FUNCTION__ << "Video:" << _mediaData.hasVideo;
			emit hasVideoChanged(_mediaData.hasVideo);
			//emit mplayerFullyLoaded();
		}

		//Pause
		else if (rx_paused.indexIn(line) > -1) {
			changeState(Phonon::PausedState);
		}

		//Stream title and url
		else if (rx_stream_title.indexIn(line) > -1) {
			QString title = rx_stream_title.cap(1);
			QString url = rx_stream_title.cap(2);
			qDebug() << __FUNCTION__ << "Stream title:" << title;
			qDebug() << __FUNCTION__ << "Stream url:" << url;
			_mediaData.title = title;
			if (!url.isEmpty() && url.at(url.size() - 1) == '/') {
				url.remove(url.size() - 1, 1);
			}
			_mediaData.streamUrl = url;

			emit mediaDataChanged(_mediaData);
		}

		//Stream title only
		else if (rx_stream_title_only.indexIn(line) > -1) {
			QString title = rx_stream_title_only.cap(1);
			qDebug() << __FUNCTION__ << "Stream title:" << title;
			_mediaData.title = title;

			emit mediaDataChanged(_mediaData);
		}


		//The following things are not sent when the file has started to play
		//(or if sent, GUI will ignore anyway...)
		//So not process anymore, if video is playing to save some time
		if (_currentState == Phonon::PlayingState) {
			return;
		}
		///


		else if ((_mplayerVersion == MPlayerProcess::MPLAYER_VERSION_NOTFOUND) &&
				(line.startsWith("MPlayer "))) {
			_mplayerVersion = MPlayerVersion::parse(line);
		}

		//Stream name
		else if (rx_stream_name.indexIn(line) > -1) {
			QString name = rx_stream_name.cap(1);
			qDebug() << __FUNCTION__ << "Stream name:" << name;
			_mediaData.streamName = name;
		}

		//Stream genre
		else if (rx_stream_genre.indexIn(line) > -1) {
			QString genre = rx_stream_genre.cap(1);
			qDebug() << __FUNCTION__ << "Stream genre:" << genre;
			_mediaData.streamGenre = genre;
		}

		//Stream website
		else if (rx_stream_website.indexIn(line) > -1) {
			QString website = rx_stream_website.cap(1);
			qDebug() << __FUNCTION__ << "Stream website:" << website;
			if (!website.isEmpty() && website.at(website.size() - 1) == '/') {
				website.remove(website.size() - 1, 1);
			}
			_mediaData.streamWebsite = website;
		}

		//Subtitle
		//static QRegExp rx_subtitle("^ID_(SUBTITLE|FILE_SUB|VOBSUB)_ID=(\\d+)");
		else if (rx_subtitle.indexIn(line) > -1) {
			//DVD line example:

			//subtitle ( sid ): 1 language: en
			//ID_SUBTITLE_ID=1
			//ID_SID_1_LANG=en

			//subtitle ( sid ): 3 language: fr
			//ID_SUBTITLE_ID=3
			//ID_SID_3_LANG=fr

			//subtitle ( sid ): 4 language: unknown
			//ID_SUBTITLE_ID=4
			//Warning! ---> No ID_SID...

			//.str file example:
			//SUB: Detected subtitle file format: subviewer
			//SUB: Read 612 subtitles.
			//ID_FILE_SUB_ID=0
			//ID_FILE_SUB_FILENAME=D:/The Ring CD1.srt
			//SUB: Added subtitle file (1): D:/The Ring CD1.srt

			//Matroska line example:
			//ID_SUBTITLE_ID=0
			//ID_SID_0_NAME=Piste de présentation
			//[mkv] Track ID 4: subtitles (S_TEXT/UTF8) Piste de présentation, -sid 0, -slang mis
			//ID_SUBTITLE_ID=1
			//ID_SID_1_LANG=fre
			//[mkv] Track ID 5: subtitles (S_VOBSUB), -sid 1, -slang fre
			//ID_SUBTITLE_ID=2
			//ID_SID_2_LANG=eng

			//int id = rx_subtitle.cap(2).toInt();
			const QString type = rx_subtitle.cap(1);

			if (type == "FILE_SUB") {
			} else if (type == "VOBSUB") {
			} else if (type == "SUBTITLE") {
			}
		}

		//Subtitle
		//static QRegExp rx_sid("^ID_(SID|VSID)_(\\d+)_(LANG|NAME)=(.*)");
		else if (rx_sid.indexIn(line) > -1) {
			int id = rx_sid.cap(2).toInt();
			const QString lang = rx_sid.cap(4);
			const QString attr = rx_sid.cap(3);
			const QString type = rx_sid.cap(1);
			qDebug() << __FUNCTION__ << "Subtitle id:" << id << "lang:" << lang << "type:" << type << "attr:" << attr;

			if (type == "VSID") {
			} else if (type == "SID") {
			}

			if (attr == "NAME") {
			} else if (attr == "LANG") {
			}

			emit subtitleAdded(id, lang, type);
		}

		//Subtitle
		//static QRegExp rx_subtitle_file("^SUB: Added subtitle file \\((\\d+)\\): (.*)");
		else if (rx_subtitle_file.indexIn(line) > -1) {
			//MPlayer make the id start at number 1,
			//we want it to start at number 0
			int id = rx_subtitle_file.cap(1).toInt() - 1;
			const QString fileName = rx_subtitle_file.cap(2);
			qDebug() << __FUNCTION__ << "Subtitle id:" << id << "file:" << fileName;

			emit subtitleAdded(id, fileName, "file");

			if (id == 0) {
				qDebug() << __FUNCTION__ << "Current subtitle changed:" << id;
				emit subtitleChanged(0);
			}
		}

		//AO
		else if (rx_ao.indexIn(line) > -1) {
			//emit receivedAO(rx_ao.cap(1));
		}

		//DVD and Matroska audio tracks
		else if (rx_audio_mat.indexIn(line) > -1) {
			//DVD examples:
			//ID_AUDIO_ID=129
			//ID_AID_129_LANG=fr
			//ID_AUDIO_ID=128
			//ID_AID_128_LANG=en

			//Matroska examples:
			//[mkv] Track ID 1: video (V_REAL/RV40), -vid 0
			//ID_AUDIO_ID=0
			//ID_AID_0_LANG=fre
			//[mkv] Track ID 3: audio (A_AAC/MPEG4/LC/SBR), -aid 1, -alang eng
			//ID_SUBTITLE_ID=0
			//ID_SID_0_NAME=Piste de présentation
			//[mkv] Track ID 4: subtitles (S_TEXT/UTF8) Piste de présentation, -sid 0, -slang mis
			//ID_SUBTITLE_ID=1
			//ID_SID_1_LANG=fre
			//[mkv] Track ID 5: subtitles (S_VOBSUB), -sid 1, -slang fre
			//ID_SUBTITLE_ID=2
			//ID_SID_2_LANG=eng
			//[mkv] Track ID 6: subtitles (S_VOBSUB), -sid 2, -slang eng
			//[mkv] Will play video track 1.
			//Matroska file format detected.
			//VIDEO:  [RV40]  704x296  24bpp  25.000 fps    0.0 kbps ( 0.0 kbyte/s)

			int id = rx_audio_mat.cap(1).toInt();
			QString lang = rx_audio_mat.cap(3);
			QString attr = rx_audio_mat.cap(2);
			qDebug() << __FUNCTION__ << "Audio id:" << id << "lang:" << lang << "attr:" << attr;

			if (attr == "NAME") {
				//lang=english, spanish...
				//_mediaData.audioTrackList.addName(id, lang);
			} else if (attr == "LANG") {
				//lang=en, fr...
				//_mediaData.audioTrackList.addLang(id, lang);
			}

			emit audioChannelAdded(id, lang);
		}

		//static QRegExp rx_mkvchapters("\\[mkv\\] Chapter (\\d+) from (.*) to (.*), (.*)");
		//Matroska chapters
		else if (rx_mkvchapters.indexIn(line) != -1) {
			//Examples:
			//[mkv] Chapter 0 from 00:10:09.800 to 00:00:00.000, La Cellule
			//[mkv] Chapter 1 from 00:15:02.080 to 00:00:00.000, Plus l'on Approche de César
			//[mkv] Chapter 2 from 00:19:16.400 to 00:00:00.000, La Compagnie Charlie
			//[mkv] Chapter 3 from 00:24:41.520 to 00:00:00.000, Guadalcanal

			int id = rx_mkvchapters.cap(1).toInt();
			QString from = rx_mkvchapters.cap(2);
			QString to = rx_mkvchapters.cap(3);
			QString title = rx_mkvchapters.cap(4);
			qDebug() << __FUNCTION__ << "mkv chapter:" << id << "title:" << title << "from:" << from << "to:" << to;

			emit mkvChapterAdded(id, title, from, to);
		}

		//VCD titles
		/*else if (rx_vcd.indexIn(line) > -1) {
			int ID = rx_vcd.cap(1).toInt();
			QString length = rx_vcd.cap(2);
			//_mediaData.titles.addID(ID);
			_mediaData.titles.addName(ID, length);
		}
		else

		//Audio CD titles
		if (rx_cdda.indexIn(line) > -1) {
			int ID = rx_cdda.cap(1).toInt();
			QString length = rx_cdda.cap(2);
			double duration = 0;
			QRegExp r("(\\d+):(\\d+):(\\d+)");
			if (r.indexIn(length) > -1) {
				duration = r.cap(1).toInt() * 60;
				duration += r.cap(2).toInt();
			}
			_mediaData.titles.addID(ID);
			//QString name = QString::number(ID) + " (" + length + ")";
			//_mediaData.titles.addName(ID, name);
			_mediaData.titles.addDuration(ID, duration);
		}
		else*/

		//DVD titles
		else if (rx_titles.indexIn(line) > -1) {
			//Available DVD titles
			//int titles = rx_title.cap(1).toInt();
		}

		else if (rx_title.indexIn(line) > -1) {
			//DVD example:
			//ID_DVD_TITLES=8
			//ID_DVD_TITLE_1_CHAPTERS=2
			//ID_DVD_TITLE_1_ANGLES=1
			//ID_DVD_TITLE_2_CHAPTERS=12
			//ID_DVD_TITLE_2_ANGLES=1
			//ID_DVD_TITLE_1_LENGTH=18.560
			//ID_DVD_TITLE_2_LENGTH=5055.000
			//ID_DVD_DISC_ID=6B5CDFED561E882B949047C87A88BCB4
			//ID_DVD_CURRENT_TITLE=1

			int titleId = rx_title.cap(1).toInt();
			const QString attr = rx_title.cap(2);

			if (attr == "CHAPTERS") {
				int chapters = rx_title.cap(3).toInt();
				qDebug() << __FUNCTION__ << "DVD titleId:" << titleId << "chapters:" << chapters;

				emit chapterAdded(titleId, chapters);
			}

			else if (attr == "ANGLES") {
				int angles = rx_title.cap(3).toInt();
				qDebug() << __FUNCTION__ << "DVD titleId:" << titleId << "angles:" << angles;

				emit angleAdded(titleId, angles);
			}

			else if (attr == "LENGTH") {
				double length = rx_title.cap(3).toDouble();
				qDebug() << __FUNCTION__ << "DVD titleId:" << titleId << "length:" << length << "attr:" << attr;

				emit titleAdded(titleId, (int) (length * SECONDS_CONVERTION));
			}
		}

		//Creating index
		else if (rx_create_index.indexIn(line) > -1) {
			emit receivedCreatingIndex(line);
		}

		//Catch resolving message
		else if (rx_resolving.indexIn(line) > -1) {
			QString msg = rx_resolving.cap(1);
			qDebug() << __FUNCTION__ << "Resolving:" << msg;
			emit resolvingMessageReceived(msg);
		}

		//Catch resolving failed
		else if (rx_resolving_failed.indexIn(line) > -1) {
			_errorString = line;
			_errorType = Phonon::NormalError;
			changeState(Phonon::ErrorState);
		}

		//Catch connecting message
		else if (rx_connecting.indexIn(line) > -1) {
			QString msg = rx_connecting.cap(1);
			qDebug() << __FUNCTION__ << "Connecting:" << msg;
			emit connectingMessageReceived(msg);
			changeState(Phonon::BufferingState);
		}

		else if (rx_read_failed.indexIn(line) > -1) {
			_errorString = "Cannot read the network stream";
			_errorType = Phonon::NormalError;
			changeState(Phonon::ErrorState);
		}

		//Catch cache messages
		else if (rx_cache_fill.indexIn(line) > -1) {
			QString tmp = rx_cache_fill.cap(1);
			tmp = tmp.trimmed();
			float percentFilled = tmp.toFloat();
			qDebug() << __FUNCTION__ << "Cache %:" << percentFilled << tmp;
			emit bufferStatus(static_cast<int>(percentFilled));
		}

		//Meta data infos

		//Title
		else if (rx_clip_title.indexIn(line) > -1) {
			QString title = rx_clip_title.cap(2);
			qDebug() << __FUNCTION__ << "Clip title:" << title;
			_mediaData.title = title;
		}

		//Artist
		else if (rx_clip_artist.indexIn(line) > -1) {
			QString artist = rx_clip_artist.cap(1);
			qDebug() << __FUNCTION__ << "Clip artist:" << artist;
			_mediaData.artist = artist;
		}

		//Author
		else if (rx_clip_author.indexIn(line) > -1) {
			QString author = rx_clip_author.cap(1);
			qDebug() << __FUNCTION__ << "Clip author:" << author;
			_mediaData.author = author;
		}

		//Album
		else if (rx_clip_album.indexIn(line) > -1) {
			QString album = rx_clip_album.cap(1);
			qDebug() << __FUNCTION__ << "Clip album:" << album;
			_mediaData.album = album;
		}

		//Genre
		else if (rx_clip_genre.indexIn(line) > -1) {
			QString genre = rx_clip_genre.cap(1);
			qDebug() << __FUNCTION__ << "Clip genre:" << genre;
			_mediaData.genre = genre;
		}

		//Date
		else if (rx_clip_date.indexIn(line) > -1) {
			QString date = rx_clip_date.cap(2);
			qDebug() << __FUNCTION__ << "Clip date:" << date;
			_mediaData.date = date;
		}

		//Track
		else if (rx_clip_track.indexIn(line) > -1) {
			QString track = rx_clip_track.cap(1);
			qDebug() << __FUNCTION__ << "Clip track:" << track;
			_mediaData.track = track;
		}

		//Copyright
		else if (rx_clip_copyright.indexIn(line) > -1) {
			QString copyright = rx_clip_copyright.cap(1);
			qDebug() << __FUNCTION__ << "Clip copyright:" << copyright;
			_mediaData.copyright = copyright;
		}

		//Comment
		else if (rx_clip_comment.indexIn(line) > -1) {
			QString comment = rx_clip_comment.cap(1);
			qDebug() << __FUNCTION__ << "Clip comment:" << comment;
			_mediaData.comment = comment;
		}

		//Software
		else if (rx_clip_software.indexIn(line) > -1) {
			QString software = rx_clip_software.cap(1);
			qDebug() << __FUNCTION__ << "Clip software:" << software;
			_mediaData.software = software;
		}

		//Catch "Starting playback..." message
		else if (rx_play.indexIn(line) > -1) {
			//OK, now all the media datas should be in clean state
			//Second time we emit mediaLoaded(), this one is usefull for DVD with angles/chapters/subtitles...
			//This must be changed, see MediaObject::mediaLoaded()
			emit mediaLoaded();
			emit mediaDataChanged(_mediaData);

			if (_mediaData.hasVideo) {
				//If we have a video to display, wait for getting the video size
				//before to be in PlayingState
				//This is a bugfix for mediaplayer example from Trolltech
			} else {
				//For audio streams, it's ok we are in PlayingState
				changeState(Phonon::PlayingState);
			}
		}

		//Generic things
		if (rx_generic.indexIn(line) > -1) {
			const QString tag = rx_generic.cap(1);
			const QString value = rx_generic.cap(2);

			if (tag == "ID_VIDEO_ID") {
				//First string to tell us that the media contains a video track
				_mediaData.hasVideo = true;
				qDebug() << __FUNCTION__ << "Video:" << _mediaData.hasVideo;
				emit hasVideoChanged(_mediaData.hasVideo);
			}

			else if (tag == "ID_AUDIO_ID") {
				//First string to tell us that the media contains an audio track
				/*int audioId = value.toInt();
				qDebug() << __FUNCTION__ << "ID_AUDIO_ID:" << audioId;
				md.audios.addID(audioId);*/
			}

			else if (tag == "ID_LENGTH") {
				_mediaData.totalTime = (qint64) (value.toDouble() * SECONDS_CONVERTION);
				qDebug() << __FUNCTION__ << "Media total time:" << _mediaData.totalTime;
				emit totalTimeChanged(_mediaData.totalTime);
			}

			else if (tag == "ID_SEEKABLE") {
				_mediaData.isSeekable = value.toInt();
				qDebug() << __FUNCTION__ << "Media seekable:" << _mediaData.isSeekable;
				emit seekableChanged(_mediaData.isSeekable);
			}

			else if (tag == "ID_VIDEO_WIDTH") {
				_mediaData.videoWidth = value.toInt();
				qDebug() << __FUNCTION__ << "Video width:" << _mediaData.videoWidth;
			}

			else if (tag == "ID_VIDEO_HEIGHT") {
				_mediaData.videoHeight = value.toInt();
				qDebug() << __FUNCTION__ << "Video height:" << _mediaData.videoHeight;
			}

			else if (tag == "ID_VIDEO_ASPECT") {
				_mediaData.videoAspectRatio = value.toDouble();
				if (_mediaData.videoAspectRatio == 0.0) {
					//I hope width & height are already set
					_mediaData.videoAspectRatio = (double) _mediaData.videoWidth / _mediaData.videoHeight;
				}
				qDebug() << __FUNCTION__ << "Video aspect:" << _mediaData.videoAspectRatio;
			}

			else if (tag == "ID_DVD_DISC_ID") {
				//_mediaData.dvd_id = value;
				qDebug() << __FUNCTION__ << "DVD disc Id:" << value;
			}

			else if (tag == "ID_DEMUXER") {
				_mediaData.demuxer = value;
			}

			else if (tag == "ID_VIDEO_FORMAT") {
				_mediaData.videoFormat = value;
			}

			else if (tag == "ID_AUDIO_FORMAT") {
				_mediaData.audioFormat = value;
			}

			else if (tag == "ID_VIDEO_BITRATE") {
				_mediaData.videoBitrate = value.toInt();
			}

			else if (tag == "ID_VIDEO_FPS") {
				_mediaData.videoFPS = value.toDouble();
				qDebug() << __FUNCTION__ << "Video FPS:" << _mediaData.videoFPS;
			}

			else if (tag == "ID_AUDIO_BITRATE") {
				_mediaData.audioBitrate = value.toInt();
			}

			else if (tag == "ID_AUDIO_RATE") {
				_mediaData.audioRate = value.toInt();
			}

			else if (tag == "ID_AUDIO_NCH") {
				_mediaData.audioNbChannels = value.toInt();
			}

			else if (tag == "ID_VIDEO_CODEC") {
				_mediaData.videoCodec = value;
			}

			else if (tag == "ID_AUDIO_CODEC") {
				_mediaData.audioCodec = value;
			}

			else if (tag == "ID_DVD_CURRENT_TITLE") {
				int id = value.toInt();
				if (_currentTitleId != id) {
					_currentTitleId = id;
					emit titleChanged(_currentTitleId);
				}
			}
		}
	}
}