Skip to content

Conversation

@moi15moi
Copy link
Contributor

Add FFMS_GetTrackTitle.
This is useful for tool like Aegisub that expose all the audio tracks to the user by exposing the track title

I tested this PR with this code
#include <ffms.h>
#include <stdexcept>
#include <string>
#include <memory>
#include <iostream>


int main() {
    const std::string filename = "MY_FILE.mkv";
    int index = 1;

    char errmsg[1024];
    FFMS_ErrorInfo errinfo;
    errinfo.Buffer      = errmsg;
    errinfo.BufferSize  = sizeof(errmsg);
    errinfo.ErrorType   = FFMS_ERROR_SUCCESS;
    errinfo.SubType     = FFMS_ERROR_SUCCESS;
    
    FFMS_Init(0, 0);

    FFMS_Indexer *indexer = FFMS_CreateIndexer(filename.c_str(), &errinfo);
    if (!indexer)
        throw std::runtime_error("ffms2 reported an error while calling FFMS_CreateIndexer: " + std::string(errinfo.Buffer) + ".");    

    int num_tracks = FFMS_GetNumTracksI(indexer);
    if (index >= num_tracks)
        throw std::invalid_argument("The index " + std::to_string(index) + " is not in the file " + filename + ".");    

    int track_type = FFMS_GetTrackTypeI(indexer, index);
    std::string steam_media_type = "";
    switch (track_type) {
        case FFMS_TYPE_VIDEO:
            steam_media_type = "video";
            break;
        case FFMS_TYPE_AUDIO:
            steam_media_type = "audio";
            break;
        case FFMS_TYPE_DATA:
            steam_media_type = "data";
            break;
        case FFMS_TYPE_SUBTITLE:
            steam_media_type = "subtitle";
            break;
        case FFMS_TYPE_ATTACHMENT:
            steam_media_type = "attachment";
            break;
        default:
            steam_media_type = "unknown";
            break;
    }
    std::cout << "The index  is a \"" + steam_media_type + "\" stream." << std::endl;  

    auto ffms2_index = std::unique_ptr<FFMS_Index, void(*)(FFMS_Index*)>(
        FFMS_DoIndexing2(indexer, FFMS_IEH_ABORT, &errinfo),
        FFMS_DestroyIndex
    );
    if (!ffms2_index)
        throw std::runtime_error("ffms2 reported an error while calling FFMS_DoIndexing2: " + std::string(errinfo.Buffer) + ".");
        
    auto ffms2_track = FFMS_GetTrackFromIndex(ffms2_index.get(), index);

    const char *title = FFMS_GetTrackTitle(ffms2_track);
    if (title)
    {
        std::cout << "Track title: " << std::string(title) << std::endl;
    }
    else 
    {
        std::cout << "Track title: NULL" << std::endl;
    }

    return 0;
}

@arch1t3cht

Copy link
Member

@dwbuiten dwbuiten left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't like hyper-specific APIs like this, if I am honest.

IMO it should be a generic stream metadata API, not hardcoded to one single thing someone needed once.

@moi15moi
Copy link
Contributor Author

Do you mean something like FFMS_GetVideoProperties but for tracks?

@dwbuiten
Copy link
Member

I mean something like a way to generically get metadata from a track, rather than solely title

@moi15moi
Copy link
Contributor Author

Ok, in this case, I believe I could add FFMS_TrackMetadata struct + FFMS_GetTrackMetadata function.
AVStream::metadata contain many track metadata as documented here.
I believe FFMS_TrackMetadata could just contain language and title because the other metadata seems useless. Do you think there should be any other field that we should keep?

Currently, the language field is in ISO 639-2 format. mkv file allow to specify a language in BCP47 format. I did open an issue to be able to get it: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/21257
I will wait and see if ffmpeg maintainers agree to add language_bcp before updating this PR.

@moi15moi moi15moi marked this pull request as draft December 22, 2025 18:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants