Language codes are now available for audio tracks to determine which is which.

This commit is contained in:
Scott Duensing 2023-12-04 19:57:04 -06:00
parent e1a11f49d4
commit 8d5de6db89
3 changed files with 133 additions and 52 deletions

View file

@ -322,6 +322,7 @@ int32_t apiDiscGetAudioTrack(lua_State *L);
int32_t apiDiscGetAudioTracks(lua_State *L);
int32_t apiDiscGetFrame(lua_State *L);
int32_t apiDiscGetHeight(lua_State *L);
int32_t apiDiscGetLanguage(lua_State *L);
int32_t apiDiscGetState(lua_State *L);
int32_t apiDiscGetWidth(lua_State *L);
int32_t apiDiscPause(lua_State *L);
@ -417,6 +418,7 @@ int32_t apiVideoGetAudioTracks(lua_State *L);
int32_t apiVideoGetFrame(lua_State *L);
int32_t apiVideoGetFrameCount(lua_State *L);
int32_t apiVideoGetHeight(lua_State *L);
int32_t apiVideoGetLanguage(lua_State *L);
int32_t apiVideoGetVolume(lua_State *L);
int32_t apiVideoGetWidth(lua_State *L);
int32_t apiVideoIsPlaying(lua_State *L);
@ -713,6 +715,33 @@ int32_t apiDiscGetFrame(lua_State *L) {
}
int32_t apiDiscGetLanguage(lua_State *L) {
int32_t n = lua_gettop(L);
bool result = false;
char *r = NULL;
int32_t track = -1;
double d;
VideoT *video = NULL;
if (n == 1) {
if (lua_isnumber(L, 1)) {
d = lua_tonumber(L, 1); track = (int32_t)d;
r = videoGetLanguage(_global.videoHandle, track);
result = true;
}
}
if (result) {
luaTrace(L, "discGetLanguage", "%d %s", track, r);
} else {
luaDie(L, "discGetLanguage", "Failed!");
}
lua_pushstring(L, r);
return 1;
}
int32_t apiDiscPause(lua_State *L) {
(void)L;
if (!_global.discStopped) {
@ -2733,6 +2762,40 @@ int32_t apiVideoGetFrameCount(lua_State *L) {
}
int32_t apiVideoGetLanguage(lua_State *L) {
int32_t n = lua_gettop(L);
bool result = false;
char *r = NULL;
int32_t id = -1;
int32_t track = -1;
double d;
VideoT *video = NULL;
if (n == 2) {
if (lua_isnumber(L, 1)) {
if (lua_isnumber(L, 2)) {
d = lua_tonumber(L, 1); id = (int32_t)d;
d = lua_tonumber(L, 2); track = (int32_t)d;
// Get our video structure
HASH_FIND_INT(_global.videoList, &id, video);
if (!video) luaDie(L, "videoGetLanguage", "No video at index %d in apiVideoGetLanguage.", id);
r = videoGetLanguage(video->handle, track);
result = true;
}
}
}
if (result) {
luaTrace(L, "videoGetLanguage", "%d %d %s", id, track, r);
} else {
luaDie(L, "videoGetLanguage", "Failed!");
}
lua_pushstring(L, r);
return 1;
}
int32_t apiVideoGetHeight(lua_State *L) {
int32_t n = lua_gettop(L);
bool result = false;
@ -4559,6 +4622,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
lua_register(_global.luaContext, "discGetAudioTracks", apiDiscGetAudioTracks);
lua_register(_global.luaContext, "discGetFrame", apiDiscGetFrame);
lua_register(_global.luaContext, "discGetHeight", apiDiscGetHeight);
lua_register(_global.luaContext, "discGetLanguage", apiDiscGetLanguage);
lua_register(_global.luaContext, "discGetState", apiDiscGetState);
lua_register(_global.luaContext, "discGetWidth", apiDiscGetWidth);
lua_register(_global.luaContext, "discPause", apiDiscPause);
@ -4654,6 +4718,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
lua_register(_global.luaContext, "videoGetFrame", apiVideoGetFrame);
lua_register(_global.luaContext, "videoGetFrameCount", apiVideoGetFrameCount);
lua_register(_global.luaContext, "videoGetHeight", apiVideoGetHeight);
lua_register(_global.luaContext, "videoGetLanguage", apiVideoGetLanguage);
lua_register(_global.luaContext, "videoGetVolume", apiVideoGetVolume);
lua_register(_global.luaContext, "videoGetWidth", apiVideoGetWidth);
lua_register(_global.luaContext, "videoIsPlaying", apiVideoIsPlaying);

View file

@ -36,6 +36,7 @@
typedef struct AudioStreamS {
FFMS_AudioSource *audioSource;
const FFMS_AudioProperties *audioProps;
char *language;
} AudioStreamT;
#pragma GCC diagnostic push
@ -194,6 +195,8 @@ FFMS_Index *_createIndex(char *filename, char *indexPath, bool hasVideo, bool ha
return index;
}
#include <libavformat/avformat.h>
#include <libavutil/dict.h>
int32_t _loadVideoAndAudio(char *vFilename, char *aFilename, char *indexPath, bool stretchVideo, SDL_Renderer *renderer) {
int32_t pixelFormats[2];
@ -205,6 +208,8 @@ int32_t _loadVideoAndAudio(char *vFilename, char *aFilename, char *indexPath, bo
int32_t count = 0;
FFMS_Track *track = NULL;
int32_t ttype = FFMS_TYPE_UNKNOWN;
AVFormatContext *fmt_ctx = NULL;
AVDictionaryEntry *tag = NULL;
// Create new videoPlayer
v = calloc(1, sizeof(VideoPlayerT));
@ -248,34 +253,11 @@ int32_t _loadVideoAndAudio(char *vFilename, char *aFilename, char *indexPath, bo
if (FFMS_SetOutputFormatV2(v->videoSource, pixelFormats, v->propFrame->EncodedWidth, v->propFrame->EncodedHeight, FFMS_RESIZER_BICUBIC, &v->errInfo)) utilDie("%s", v->errInfo.Buffer);
// Find audio track(s)
//utilSay("Tracks in file: %d", FFMS_GetNumTracks(aIndex));
for (x=0; x<FFMS_GetNumTracks(aIndex); x++) {
track = FFMS_GetTrackFromIndex(aIndex, x);
ttype = FFMS_GetTrackType(track);
// Just count the tracks for now.
if (ttype == FFMS_TYPE_AUDIO) count++;
/*
switch (ttype) {
case FFMS_TYPE_UNKNOWN:
utilSay("Track %d is FFMS_TYPE_UNKNOWN", x);
break;
case FFMS_TYPE_VIDEO:
utilSay("Track %d is FFMS_TYPE_VIDEO", x);
break;
case FFMS_TYPE_AUDIO:
utilSay("Track %d is FFMS_TYPE_AUDIO", x);
break;
case FFMS_TYPE_DATA:
utilSay("Track %d is FFMS_TYPE_DATA", x);
break;
case FFMS_TYPE_SUBTITLE:
utilSay("Track %d is FFMS_TYPE_SUBTITLE", x);
break;
case FFMS_TYPE_ATTACHMENT:
utilSay("Track %d is FFMS_TYPE_ATTACHMENT", x);
break;
}
*/
}
if (count > 0) {
// Allocate space for the tracks.
@ -289,6 +271,20 @@ int32_t _loadVideoAndAudio(char *vFilename, char *aFilename, char *indexPath, bo
v->audioSourceCount++;
}
}
// Use ffmpeg directly to figure out language IDs for audio tracks
if (avformat_open_input(&fmt_ctx, aFilename, NULL, NULL) >= 0) {
count = 0;
for (x=0; x<fmt_ctx->nb_streams; x++) {
if (fmt_ctx->streams[x]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
while ((tag = (AVDictionaryEntry *)av_dict_iterate(fmt_ctx->streams[x]->metadata, tag))) {
if (utilStricmp("language", tag->key) == 0) {
v->audio[count++].language = strdup(tag->value);
}
}
}
}
avformat_close_input(&fmt_ctx);
}
// Current audio track.
v->currentAudioTrack = 0;
}
@ -463,6 +459,24 @@ int64_t videoGetFrameCount(int32_t playerHandle) {
}
char *videoGetLanguage(int32_t playerHandle, int32_t audioTrack) {
VideoPlayerT *v = NULL;
char *r = NULL;
// Get our player structure
HASH_FIND_INT(_videoPlayerHash, &playerHandle, v);
if (!v) utilDie("No video player at index %d in videoGetHeight.", playerHandle);
if ((audioTrack >= 0) && (audioTrack < v->audioSourceCount)) {
r = v->audio[audioTrack].language;
} else {
utilDie("Invalid audio track in videoSetAudioTrack.");
}
return r;
}
int32_t videoGetHeight(int32_t playerHandle) {
VideoPlayerT *v = NULL;
@ -627,6 +641,7 @@ int32_t videoUnload(int32_t playerHandle) {
SDL_FreeAudioStream(v->audioStream);
free(v->audioBuffer);
for (x=0; x<v->audioSourceCount; x++) {
if (v->audio[x].language) free(v->audio[x].language);
FFMS_DestroyAudioSource(v->audio[x].audioSource);
}
free(v->audio);

View file

@ -39,6 +39,7 @@ int32_t videoGetAudioTracks(int32_t playerHandle);
int64_t videoGetFrame(int32_t playerHandle);
int64_t videoGetFrameCount(int32_t playerHandle);
int32_t videoGetHeight(int32_t playerHandle);
char *videoGetLanguage(int32_t playerHandle, int32_t audioTrack);
int32_t videoGetWidth(int32_t playerHandle);
int32_t videoGetVolume(int32_t playerHandle, int32_t *leftPercent, int32_t *rightPercent);
int32_t videoLoad(char *filename, char *indexPath, bool stretchVideo, SDL_Renderer *renderer);