Code: Select all
const
  csAC3TranscodingParams = '-i "%s" -acodec %s -ar 48000 -ab %d -map 0:%d -y -f %s "%s"';
  
function GetAudioBitrate(const aAudioCodec: string; aAudioBitrate: Integer): Integer;
begin
  if MatchText(aAudioCodec, ['MP2', 'MP3']) and (aAudioBitrate > 320000) then
    Result := 320000
  else
    Result := aAudioBitrate
end;
  
function GetAudioCodec(const aAudioCodec: string): string;
begin
  if (aAudioCodec = '') or SameText(aAudioCodec, 'AC3') then
    Result := 'ac3'
  else if SameText(aAudioCodec, 'AAC') then
    Result := 'libfaac'
  else if SameText(aAudioCodec, 'MP3') then
    Result := 'libmp3lame'
  else if SameText(aAudioCodec, 'MP2') then
    Result := 'mp2'
  else if SameText(aAudioCodec, 'WMA') then
    Result := 'wmav2'
  else
    Result := aAudioCodec
end;
function GetTsMuxerAudioCodec(const aAudioCodec: string): string;
begin
  if (aAudioCodec = '') or SameText(aAudioCodec, 'AC3') then
    Result := 'A_AC3'
  else if SameText(aAudioCodec, 'AAC') then
    Result := 'A_AAC'
  else if SameText(aAudioCodec, 'MP3') then
    Result := 'A_MP3'
  else if SameText(aAudioCodec, 'MP2') then
    Result := 'A_MP3'
  else
    Result := ''  
end;
function GetAudioFormat(const aAudioCodec: string): string;
begin
  if (aAudioCodec = '') or SameText(aAudioCodec, 'AC3') then
    Result := 'ac3'
  else if SameText(aAudioCodec, 'AAC') then
    Result := 'adts'
  else if SameText(aAudioCodec, 'MP3') then
    Result := 'mp3'
  else if SameText(aAudioCodec, 'MP2') then
    Result := 'mp2'
  else
    Result := aAudioCodec
end;
function SameAudioCodec(const aAudioCodec: string; aCodecID: Integer): Boolean;
begin
  if (aAudioCodec = '') or SameText(aAudioCodec, 'AC3') then
    Result := aCodecID = CODEC_ID_AC3
  else if SameText(aAudioCodec, 'AAC') then
    Result := aCodecID = CODEC_ID_AAC
  else if SameText(aAudioCodec, 'MP3') then
    Result := aCodecID = CODEC_ID_MP3
  else if SameText(aAudioCodec, 'MP2') then
    Result := aCodecID = CODEC_ID_MP2
  else if SameText(aAudioCodec, 'WMA') then
    Result := aCodecID = CODEC_ID_WMAV2
  else
    Result := False
end;
var
  i, iAudioStreamNo, iAudioCodecID, iVideoCodecID, 
  iAudioStreamID, iVideoStreamID: Integer;
  MetaFileLines: TStringList;
  sAudioInfo, sVideoInfo, sMetaFileName, 
  sInputVideoFileName, sInputAudioFileName, 
  sAC3TranscodingParams, sTimeShift,
  sFPS, sLANG: string;
  sAC3ReadPipeName, sAC3WritePipeName : Array[0..mpAudioStreams-1] of string; 
begin
    MetaFileLines := TStringList.Create;
    try
      sTimeShift := HmsGetVideoSettings(vstAudioDelay);
      if sTimeShift <> '' then
        sTimeShift := Format(', timeshift=%ss', [sTimeShift]);
      sInputVideoFileName := mpFilePath;
      sInputAudioFileName := mpFilePath;
      MetaFileLines.Add('MUXOPT --no-pcr-on-video-pid --vbr --vbv-len=500');
      iVideoCodecID := HmsGetStreamCodecID(stVideo, 0);
      if iVideoCodecID > 0 then begin   
        if (iVideoCodecID = CODEC_ID_H264) or SameText(mpVideoCodec, 'H264') then 
          sVideoInfo := 'V_MPEG4/ISO/AVC, "%s", level=4.1, insertSEI, contSPS'
        else if (iVideoCodecID = CODEC_ID_MPEG2VIDEO) or SameText(mpVideoCodec, 'MPEG2VIDEO') then
          sVideoInfo := 'V_MPEG-2, "%s"'
        else if (iVideoCodecID = CODEC_ID_VC1) or SameText(mpVideoCodec, 'VC1') then
          sVideoInfo := 'V_MS/VFW/WVC1, "%s"'
        else   
          sVideoInfo := '';
         end;          
        if sVideoInfo <> '' then begin
          if SameText(ExtractFileExt(mpFilePath), '.mkv') then begin
            iVideoStreamID := HmsGetStreamIndex(stVideo, 0) + 1;
          end else begin  
            iVideoStreamID := HmsGetStreamID(stVideo, 0);  
            if SameText(ExtractFileExt(mpFilePath), '.vob') then begin
              iVideoStreamID := iVideoStreamID and 255;
            end;
          end;
          sFPS := 'fps=%2.3f';
          sFPS := Format(sFPS, [mpFrameRate]);
          sFPS := ReplaceStr(sFPS, ',', '.');
          sVideoInfo := sVideoInfo + ', track=%d, %s, lang=';
          sLANG := HmsGetStreamLanguage(stVideo, iVideoStreamID);
          if SameText(sLANG, '') then sLANG := 'eng';
          sVideoInfo := sVideoInfo + sLANG;
          MetaFileLines.Add(Format(sVideoInfo, [sInputVideoFileName, iVideoStreamID, sFPS]));
       end;
      for i := 0 to mpAudioStreams-1 do begin
        iAudioStreamNo := i;
        sInputAudioFileName := mpFilePath;
      iAudioCodecID := HmsGetStreamCodecID(stAudio, iAudioStreamNo);
        if iAudioCodecID = CODEC_ID_AC3 then  
          sAudioInfo := 'A_AC3'
        else if iAudioCodecID = CODEC_ID_DTS then
          sAudioInfo := 'A_DTS'
        else if iAudioCodecID = CODEC_ID_MP3 then
          sAudioInfo := 'A_MP3'
        else if iAudioCodecID = CODEC_ID_AAC then
          sAudioInfo := 'A_AAC'
        else
          sAudioInfo := '';
        if sAudioInfo <> '' then begin
          if SameText(ExtractFileExt(mpFilePath), '.mkv') then begin
            iAudioStreamID := HmsGetStreamIndex(stAudio, iAudioStreamNo) + 1;
          end else begin  
            iAudioStreamID := HmsGetStreamID(stAudio, iAudioStreamNo);
            if SameText(ExtractFileExt(mpFilePath), '.vob') then begin
              iAudioStreamID := iAudioStreamID and 255;
            end
          end;    
          if not SameAudioCodec(cfgTranscodingAudioCodec, iAudioCodecID) then begin
            if HmsCreateDualPipe(sAC3ReadPipeName[i], sAC3WritePipeName[i]) then begin
              sAC3TranscodingParams := Format(csAC3TranscodingParams, 
                  [mpFilePath, GetAudioCodec(cfgTranscodingAudioCodec ), 
                   GetAudioBitrate(cfgTranscodingAudioCodec, cfgTranscodingAudioBitrate),  
                   HmsGetStreamIndex(stAudio, iAudioStreamNo), 
                   GetAudioFormat(cfgTranscodingAudioCodec), sAC3WritePipeName[i]]);
              if HmsTranscodingExecute('HMSMPEG', sAC3TranscodingParams, False) then begin     
                sInputAudioFileName := sAC3ReadPipeName[i];
                sAudioInfo := GetTsMuxerAudioCodec(cfgTranscodingAudioCodec);
                iAudioStreamID := 1;
              end  
            end   
          end;
          sAudioInfo := sAudioInfo + ', "%s", ' + 'track=%d' + sTimeShift;
          sAudioInfo := sAudioInfo + ', lang=';
          sLANG := HmsGetStreamLanguage(stAudio, iAudioStreamNo);
          if SameText(sLANG, '') then sLANG := 'eng';
          sAudioInfo := sAudioInfo + sLANG;
          MetaFileLines.Add(Format(sAudioInfo, [sInputAudioFileName, iAudioStreamID]));
        end;
        end;
          sMetaFileName := ChangeFileExt(OutputFileName, '.meta');
          MetaFileLines.SaveToFile(sMetaFileName);
          OutputFileName := ChangeFileExt(OutputFileName, '.m2ts');
          TranscodingResult := HmsTranscodingExecute('TSMUXER', '"' + sMetaFileName + '" "' + OutputFileName + '"', True);
    finally
      MetaFileLines.Free
  end  
end. Добавил передачу тсМуксеру значения фпс из потока (на всякий случай) и добавил для каждой дороги идентификатор языка (тоже на всякий случай
 Добавил передачу тсМуксеру значения фпс из потока (на всякий случай) и добавил для каждой дороги идентификатор языка (тоже на всякий случай   ). Единственный обнаруженный пока что минус - не работает перемотка и переход по времени
 ). Единственный обнаруженный пока что минус - не работает перемотка и переход по времени   Пока что это не очень страшно, но иногда нужно. Буду рыть еще.
  Пока что это не очень страшно, но иногда нужно. Буду рыть еще.Да, и пришлось добавить для AVC (h264) конвертацию в level=4.1, потому как оказалось, что телек высшие профили не понимает.
З.Ы. AVI-шек у меня нету с количеством аудио больше двух, так что с ними пока отлично справляется "Фильмы (основной)+AUDIO".
З.З.Ы. Да, и по-прежнему телик понимает только стандартные разрешения
 - тоже буду ковырять.
  - тоже буду ковырять.

 Пока всё очень коряво
  Пока всё очень коряво   и тоже спрошу Вас: а какого типа файлы Вы смотрите через HMS??? Если у Вас все фильмы в формате m2ts (или подобные), так о чем Вы тогда говорите? Сонька такие файлы понимает БЕЗ транскодирования, и только поэтому для таких файлов нормально работает перемотка, нормально переключаются звуковые дорожки и т.п. Как только Вы скормите HMS-у фильм в mkv, так сразу и начнутся свистопляски, потому как кодек видео внутри матрешки может быть практически ЛЮБЫМ, да и к звуку это же относится. А как только HMS видит, что кодек не относится к поддерживаемым клиентским устройством, так сразу же и включается транскодирование. А ВСЕ профили, которые есть в HMS, транскодируют только ОДНУ видео и ОДНУ аудиодорожку.
  и тоже спрошу Вас: а какого типа файлы Вы смотрите через HMS??? Если у Вас все фильмы в формате m2ts (или подобные), так о чем Вы тогда говорите? Сонька такие файлы понимает БЕЗ транскодирования, и только поэтому для таких файлов нормально работает перемотка, нормально переключаются звуковые дорожки и т.п. Как только Вы скормите HMS-у фильм в mkv, так сразу и начнутся свистопляски, потому как кодек видео внутри матрешки может быть практически ЛЮБЫМ, да и к звуку это же относится. А как только HMS видит, что кодек не относится к поддерживаемым клиентским устройством, так сразу же и включается транскодирование. А ВСЕ профили, которые есть в HMS, транскодируют только ОДНУ видео и ОДНУ аудиодорожку.   о переключении звука и соответствии размеров кадра. Ибо не очень-то хочется перекодировать все фильмы в m2ts, чтобы смотреть их без транскодинга. Это, во-первых, время, а во-вторых - место, ибо m2ts чаще всего будет бОльшего размера, чем mkv (даже без перекодирования, при обычном ремуксировании).
 о переключении звука и соответствии размеров кадра. Ибо не очень-то хочется перекодировать все фильмы в m2ts, чтобы смотреть их без транскодинга. Это, во-первых, время, а во-вторых - место, ибо m2ts чаще всего будет бОльшего размера, чем mkv (даже без перекодирования, при обычном ремуксировании). Буфер стоит 128 мег.
 Буфер стоит 128 мег.