SmartFarm/SOURCE/SmartFarmHMI/SmartFarmHMI_VCL_RTSP_/MPVTrack.pas
2026-09-04 10:53:44 +09:00

234 lines
5.4 KiB
ObjectPascal

unit MPVTrack;
// LibMPV track info helper classes
// Author: Edward G. (nbuyer@gmail.com)
interface
uses
SysUtils, Classes, Contnrs, MPVClient, MPVNode;
type
TMPVTrackType = (trkUnknown, trkVideo, trkAudio, trkSub);
TMPVTrackInfo = class
private
m_nSrcID: Int64; // abs id
m_eTrkType: TMPVTrackType; //video/audio/sub
m_nTrkID: Int64; // same type index
m_sTitle: string; // track title
m_sCodec: string; // codec
m_sLang: string; // lang id such as "eng"
m_nBitrate: Int64; // bitrate if avail
m_nVal1: Int64; // width / channel count
m_nVal2: Int64; // height / samplerate
m_fVal3: Double; // fps
m_bDefault: Boolean; // default
public
function LoadFromNode(cNode: TMPVNode): Boolean;
procedure Clear;
procedure Assign(cTI: TMPVTrackInfo);
public
property TrackType: TMPVTrackType read m_eTrkType;
property SrcID: Int64 read m_nSrcID;
property TrackID: Int64 read m_nTrkID;
property Title: string read m_sTitle;
property LangID: string read m_sLang;
property Codec: string read m_sCodec;
property IsDefault: Boolean read m_bDefault;
property VideoWidth: Int64 read m_nVal1;
property VideoHeight: Int64 read m_nVal2;
property VideoFPS: Double read m_fVal3;
property BitRate: Int64 read m_nBitrate;
property AudioChannel: Int64 read m_nVal1;
property AudioSampleRate: Int64 read m_nVal2;
end;
{ TMPVTrackList }
TMPVTrackList = class(TObjectList)
private
procedure SetItem(Index: Integer; AValue: TMPVTrackInfo);
function GetItem(Index: Integer): TMPVTrackInfo;
public
constructor Create;
procedure Assign(cTL: TMPVTrackList; eFilterType: TMPVTrackType = trkUnknown);
function LoadFromNode(cNode: TMPVNode): Boolean;
function FindTrack(eType: TMPVTrackType; id: Int64): TMPVTrackInfo;
public
property Items[Index: Integer]: TMPVTrackInfo read GetItem write SetItem; default;
end;
implementation
{ TMPVTrackInfo }
procedure TMPVTrackInfo.Assign(cTI: TMPVTrackInfo);
begin
m_nSrcID := cTI.SrcID;
m_eTrkType := cTI.TrackType;
m_nTrkID := cTI.m_nTrkID;
m_sTitle := cTI.Title;
m_sCodec := cTI.Codec;
m_sLang := cTI.LangID;
m_nBitrate := cTI.BitRate;
m_nVal1 := cTI.VideoWidth;
m_nVal2 := cTI.VideoHeight;
m_fVal3 := cTI.VideoFPS;
end;
procedure TMPVTrackInfo.Clear;
begin
m_nSrcID := 0;
m_eTrkType := trkUnknown;
m_nTrkID := 0;
m_sTitle := '';
m_sCodec := '';
m_sLang := '';
m_nBitrate := 0;
m_nVal1 := 0;
m_nVal2 := 0;
m_fVal3 := 0.0;
end;
function TMPVTrackInfo.LoadFromNode(cNode: TMPVNode): Boolean;
var
i: Integer;
cN: TMPVNode;
sKey, s: string;
begin
if cNode.Fmt<>MPV_FORMAT_NODE_MAP then
begin
Result := False;
Exit;
end;
Result := True;
Clear;
for i := 0 to cNode.Nodes.Count-1 do
begin
cN := cNode.Nodes.GetNode(i);
sKey := cNode.Nodes[i];
if sKey='id' then
m_nTrkID := cN.AsInt64
else if sKey='type' then
begin
s := AnsiLowercase(cN.AsString);
if s='video' then
m_eTrkType := trkVideo
else if s='audio' then
m_eTrkType := trkAudio
else if s='sub' then
m_eTrkType := trkSub
else m_eTrkType := trkUnknown;
end
else if sKey='src-id' then
m_nSrcID := cN.AsInt64
else if sKey='title' then
m_sTitle := cN.AsString
else if sKey='lang' then
m_sLang := cN.AsString
else if sKey='codec' then
m_sCodec := cN.AsString
else if sKey='default' then
m_bDefault := cN.AsBool
else if sKey='demux-w' then
m_nVal1 := cN.AsInt64
else if sKey='demux-h' then
m_nVal2 := cN.AsInt64
else if sKey= 'demux-fps' then
m_fVal3 := cN.AsDouble
else if sKey='demux-channel-count' then
m_nVal1 := cN.AsInt64
else if sKey='demux-samplerate' then
m_nVal2 := cN.AsInt64
else if sKey='demux-bitrate' then
m_nBitrate := cN.AsInt64;
// 'decoder-desc'
end;
end;
{ TMPVTrackList }
procedure TMPVTrackList.Assign(cTL: TMPVTrackList; eFilterType: TMPVTrackType);
var
i: Integer;
cTrk, cNewTrk: TMPVTrackInfo;
begin
Clear;
for i := 0 to cTL.Count-1 do
begin
cTrk := cTL[i];
if (eFilterType=trkUnknown) or (cTrk.TrackType=eFilterType) then
begin
cNewTrk := TMPVTrackInfo.Create;
cNewTrk.Assign(cTrk);
if Add(cNewTrk)<0 then cNewTrk.Free;
end;
end;
end;
procedure TMPVTrackList.SetItem(Index: Integer; AValue: TMPVTrackInfo);
begin
inherited SetItem(Index, AValue);
end;
function TMPVTrackList.GetItem(Index: Integer): TMPVTrackInfo;
begin
Result := TMPVTrackInfo(inherited GetItem(Index));
end;
constructor TMPVTrackList.Create;
begin
inherited Create(True);
end;
function TMPVTrackList.FindTrack(eType: TMPVTrackType; id: Int64): TMPVTrackInfo;
var
cTrk: TMPVTrackInfo;
i: Integer;
begin
for i := 0 to Count-1 do
begin
cTrk := GetItem(i);
if cTrk.TrackType=eType then
if cTrk.TrackID=id then
begin
Result := cTrk;
Exit;
end;
end;
Result := nil;
end;
function TMPVTrackList.LoadFromNode(cNode: TMPVNode): Boolean;
var
i: Integer;
cN: TMPVNode;
cTrk: TMPVTrackInfo;
begin
if cNode.Fmt<>MPV_FORMAT_NODE_ARRAY then
begin
Result := False;
Exit;
end;
Clear;
Result := True;
for i := 0 to cNode.Nodes.Count-1 do
begin
cN := cNode.Nodes.GetNode(i);
cTrk := TMPVTrackInfo.Create;
if cTrk.LoadFromNode(cN) then
begin
if Add(cTrk)<0 then cTrk.Free;
end else
cTrk.Free;
end;
end;
end.