Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to get meta data from media?
Forum Updated to NodeBB v4.3 + New Features

How to get meta data from media?

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 3 Posters 1.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    davecotter
    wrote on last edited by
    #1

    say i have a video, say h.264 (that i have confirmed will indeed play), and i'd like to glean some of its meta data BEFORE playing it. Like it's dimensions ("Resolution"), it's audio bitrate ("AudioBitRate"), and any of the other standard things like duration, title, artist, album etc.

    it's my understanding that QMediaPlayer knows nothing of this info (even though it provides APIs for them), until AFTER the underlying media in question has started playing? is there a way to, say "preroll" the media to get the meta data to be available, BEFORE playing? or must i actually, secretly play the media a bit and wait for a "meta data available" singnal?

    all i could find on the web suggests that the solution is the latter, that there is no "preroll" API i can call.

    This is the code i've come up with:

    void		QVideoWindow::WaitForMetaData(QMediaPlayer *playerP)
    {
    	if (!i_got_metaB) {
    		QGraphicsVideoItem		vidWid;
    
    		playerP->setVideoOutput(&vidWid);
    
    		//	metaDataAvailableChanged
    
    		i_playerP = playerP;
    		QObject::connect(
    			playerP,	&QMediaPlayer::mediaStatusChanged,
    			this,		&QVideoWindow::onMediaStatusChanged);
    
    		playerP->setVolume(0);
    		playerP->play();
    
    		QEventLoop		loop;
    
    		while (!i_got_metaB) {
    			//IdleDuration(0.1);
    			loop.processEvents();
    		}
    
    		QObject::disconnect(
    			playerP,	&QMediaPlayer::mediaStatusChanged,
    			this,		&QVideoWindow::onMediaStatusChanged);
    
    		i_playerP = NULL;
    
    		playerP->stop();
    		playerP->setPosition(0);
    		playerP->setVideoOutput((QVideoWidget *)NULL);
    
    		i_got_metaB = false;
    	}
    }
    
    void		QVideoWindow::onMediaStatusChanged(QMediaPlayer::MediaStatus mediaStatus)
    {
    	if (mediaStatus == QMediaPlayer::BufferedMedia) {
    		QString			outStr;
    		QTextStream		outStream(&outStr);
    
    		for (auto &item: i_playerP->availableMetaData()) {
    			outStream << item << ", ";
    		}
    
    		Logf("availz: %s\n", SuperString(outStr).utf8Z());
    
    		i_got_metaB = true;
    	}
    }
    

    At the time that WaitForMetaData() is called, i assure you that QMediaPlayer has been allocated with QMediaPlayer::VideoSurface, and the mp4 file path has been properly set with setMedia().

    I have tried using a QVideoWidget instead of a QGraphicsVideoItem, and I have tried connecting to the metaDataAvailableChanged signal too, to no avail.

    the issue is that my slot onMediaStatusChanged is never called (and yes it is properly designated as a slot in the header).

    1. this method seems ridiculously convoluted for something so potentially common and mundane
    2. does anyone have a FUNCTIONING bit of code that does what is needed, that they can paste in here?

    thanks!

    -dave

    1 Reply Last reply
    0
    • B Offline
      B Offline
      Bonnie
      wrote on last edited by
      #2

      In windows 10, I can get meta data after setMedia, without calling play, but it is asynchronous

      auto player = new QMediaPlayer(this);
      player->setMedia(QUrl::fromLocalFile("QTSRCDIR/qtwebengine/src/3rdparty/chromium/third_party/webrtc/examples/objc/AppRTCMobile/ios/resources/foreman.mp4"));
      connect(player, &QMediaPlayer::metaDataAvailableChanged, [=](bool avaliable){
          if(avaliable) {
              for (auto key : player->availableMetaData()) {
                  qDebug() << key << player->metaData(key);
              }
          }
      });
      

      output:

      "Duration" QVariant(qlonglong, 10001)
      "PixelAspectRatio" QVariant(QSize, QSize(1, 1))
      "Resolution" QVariant(QSize, QSize(352, 288))
      "VideoBitRate" QVariant(uint, 433960)
      "VideoCodec" QVariant(QString, "H.264 Video")
      "VideoFrameRate" QVariant(double, 30)
      

      Haven't tried that in other platforms though.

      1 Reply Last reply
      2
      • D Offline
        D Offline
        davecotter
        wrote on last edited by
        #3

        that's equivalent to my above code, which does not work. i'm on a mac, by the way.

        by "does not work" i mean the slot is never called

        1 Reply Last reply
        0
        • D Offline
          D Offline
          davecotter
          wrote on last edited by
          #4

          does anyone know how to use Qt to get meta data from a media file, on mac?

          jsulmJ 1 Reply Last reply
          0
          • D davecotter

            does anyone know how to use Qt to get meta data from a media file, on mac?

            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @davecotter You should still try @Bonnie code as yours is not exactly the same (you're using a local event loop which is actually not needed if using assynchronous nature of Qt properly, also you call play which Bonnie doesn't).
            Also you should connect a slot to https://doc.qt.io/qt-5/qmediaplayer.html#error-1 to see whether you get any errors.
            https://doc.qt.io/qt-5/qmediaplayer.html#mediaChanged, https://doc.qt.io/qt-5/qmediaplayer.html#stateChanged and https://doc.qt.io/qt-5/qmediaplayer.html#mediaStatusChanged are also worth checking.

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • D Offline
              D Offline
              davecotter
              wrote on last edited by
              #6

              i suppose it's my fault for not being clear: i have tried a half dozen solutions, INCLUDING the one proposed by @Bonnie , and none work.

              can someone who really believes this should work on a mac please try it?

              and the point is i need the data BEFORE the function exits, hence my synchronous approach.

              note i admit this DOES work fine on windows, but that's not my problem, my problem is mac. on mac the slot is never called.

              at the risk of being overly clear / verbose, i added all this code:

              		//	error
              		connect(playerP, QOverload<QMediaPlayer::Error>::of(&QMediaPlayer::error),
              			[=](QMediaPlayer::Error error) {
              				qDebug() << error;
              			}
              		);
              
              		//	metaDataAvailableChanged
              		connect(playerP, &QMediaPlayer::metaDataAvailableChanged,
              			[=](bool avaliable) {
              				if (avaliable) {
              					for (auto key : playerP->availableMetaData()) {
              						qDebug() << key << playerP->metaData(key);
              					}
              				}
              			}
              		);
              
              		//	mediaChanged
              		connect(playerP, &QMediaPlayer::mediaChanged,
              			[=](const QMediaContent &media) {
              				qDebug() << "mediaChanged";
              			}
              		);
              
              		//	mediaStatusChanged
              		connect(playerP, &QMediaPlayer::mediaStatusChanged,
              			[=](QMediaPlayer::MediaStatus status) {
              				qDebug() << status;
              			}
              		);
              
              		//	stateChanged
              		connect(playerP, &QMediaPlayer::stateChanged,
              			[=](QMediaPlayer::State state) {
              				qDebug() << state;
              			}
              		);
              

              on mac: NONE of the slots are called.
              on win: they are called as expected:
              metaDataAvailableChanged is called first, printing out a nice list of all the meta data
              mediaStatusChanged is then called, showing "loadedMedia"

              jsulmJ 1 Reply Last reply
              0
              • D davecotter

                i suppose it's my fault for not being clear: i have tried a half dozen solutions, INCLUDING the one proposed by @Bonnie , and none work.

                can someone who really believes this should work on a mac please try it?

                and the point is i need the data BEFORE the function exits, hence my synchronous approach.

                note i admit this DOES work fine on windows, but that's not my problem, my problem is mac. on mac the slot is never called.

                at the risk of being overly clear / verbose, i added all this code:

                		//	error
                		connect(playerP, QOverload<QMediaPlayer::Error>::of(&QMediaPlayer::error),
                			[=](QMediaPlayer::Error error) {
                				qDebug() << error;
                			}
                		);
                
                		//	metaDataAvailableChanged
                		connect(playerP, &QMediaPlayer::metaDataAvailableChanged,
                			[=](bool avaliable) {
                				if (avaliable) {
                					for (auto key : playerP->availableMetaData()) {
                						qDebug() << key << playerP->metaData(key);
                					}
                				}
                			}
                		);
                
                		//	mediaChanged
                		connect(playerP, &QMediaPlayer::mediaChanged,
                			[=](const QMediaContent &media) {
                				qDebug() << "mediaChanged";
                			}
                		);
                
                		//	mediaStatusChanged
                		connect(playerP, &QMediaPlayer::mediaStatusChanged,
                			[=](QMediaPlayer::MediaStatus status) {
                				qDebug() << status;
                			}
                		);
                
                		//	stateChanged
                		connect(playerP, &QMediaPlayer::stateChanged,
                			[=](QMediaPlayer::State state) {
                				qDebug() << state;
                			}
                		);
                

                on mac: NONE of the slots are called.
                on win: they are called as expected:
                metaDataAvailableChanged is called first, printing out a nice list of all the meta data
                mediaStatusChanged is then called, showing "loadedMedia"

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @davecotter Sorry, I don't have Mac, so can't test.

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                0
                • D Offline
                  D Offline
                  davecotter
                  wrote on last edited by
                  #8

                  there is a minimal project available in the bug report if someone would like to see the problem.

                  note the major problem (no signals) only happens on mac, but there ARE problems on windows, which you can see by reading the bug report.

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved