mirror of
https://github.com/n00mkrad/flowframes.git
synced 2026-07-11 21:11:00 +02:00
Fixed audio compatibility check, improved lossless audio transfer
This commit is contained in:
@@ -97,7 +97,10 @@ namespace Flowframes.Media
|
||||
|
||||
public static bool ContainerSupportsAllAudioFormats (Interpolate.OutMode outMode, List<string> codecs)
|
||||
{
|
||||
foreach(string format in codecs)
|
||||
if(codecs.Count < 1)
|
||||
Logger.Log($"Warning: ContainerSupportsAllAudioFormats() was called, but codec list has {codecs.Count} entries.", true, false, "ffmpeg");
|
||||
|
||||
foreach (string format in codecs)
|
||||
{
|
||||
if (!ContainerSupportsAudioFormat(outMode, format))
|
||||
return false;
|
||||
@@ -108,7 +111,8 @@ namespace Flowframes.Media
|
||||
|
||||
public static bool ContainerSupportsAudioFormat (Interpolate.OutMode outMode, string format)
|
||||
{
|
||||
format = format.Remove(".");
|
||||
string alias = GetAudioExt(format);
|
||||
Logger.Log($"Checking if {outMode} supports audio format '{format}' (alias {alias})", true, false, "ffmpeg");
|
||||
|
||||
string[] formatsMp4 = new string[] { "m4a", "ac3", "dts" };
|
||||
string[] formatsMkv = new string[] { "m4a", "ac3", "dts", "ogg", "mp2", "wav" };
|
||||
@@ -118,11 +122,11 @@ namespace Flowframes.Media
|
||||
|
||||
switch (outMode)
|
||||
{
|
||||
case Interpolate.OutMode.VidMp4: return formatsMp4.Contains(format);
|
||||
case Interpolate.OutMode.VidMkv: return formatsMkv.Contains(format);
|
||||
case Interpolate.OutMode.VidWebm: return formatsWebm.Contains(format);
|
||||
case Interpolate.OutMode.VidProRes: return formatsProres.Contains(format);
|
||||
case Interpolate.OutMode.VidAvi: return formatsAvi.Contains(format);
|
||||
case Interpolate.OutMode.VidMp4: return formatsMp4.Contains(alias);
|
||||
case Interpolate.OutMode.VidMkv: return formatsMkv.Contains(alias);
|
||||
case Interpolate.OutMode.VidWebm: return formatsWebm.Contains(alias);
|
||||
case Interpolate.OutMode.VidProRes: return formatsProres.Contains(alias);
|
||||
case Interpolate.OutMode.VidAvi: return formatsAvi.Contains(alias);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -147,17 +151,29 @@ namespace Flowframes.Media
|
||||
|
||||
public static string GetAudioExt(string videoFile, int streamIndex = -1)
|
||||
{
|
||||
switch (FfmpegCommands.GetAudioCodec(videoFile, streamIndex))
|
||||
return GetAudioExt(FfmpegCommands.GetAudioCodec(videoFile, streamIndex));
|
||||
}
|
||||
|
||||
public static string GetAudioExt (string codec)
|
||||
{
|
||||
if (codec.StartsWith("pcm_"))
|
||||
return "wav";
|
||||
|
||||
switch (codec)
|
||||
{
|
||||
case "vorbis": return "ogg";
|
||||
case "opus": return "ogg";
|
||||
case "mp2": return "mp2";
|
||||
case "mp3": return "mp3";
|
||||
case "aac": return "m4a";
|
||||
case "ac3": return "ac3";
|
||||
case "eac3": return "ac3";
|
||||
case "dts": return "dts";
|
||||
default: return "wav";
|
||||
case "alac": return "wav";
|
||||
case "flac": return "wav";
|
||||
}
|
||||
|
||||
return "unsupported";
|
||||
}
|
||||
|
||||
public static string GetAudioFallbackArgs (Interpolate.OutMode outMode)
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Flowframes.Media
|
||||
|
||||
foreach (AudioTrack track in audioTracks)
|
||||
{
|
||||
if (Interpolate.canceled) break;
|
||||
if (I.canceled) break;
|
||||
|
||||
string audioExt = Utils.GetAudioExt(inputFile, track.streamIndex);
|
||||
string outPath = Path.Combine(outFolder, $"{track.streamIndex}_{track.metadata}_audio.{audioExt}");
|
||||
@@ -37,15 +37,15 @@ namespace Flowframes.Media
|
||||
string args = $"{trim[0]} -i {inputFile.Wrap()} {trim[1]} -map 0:{track.streamIndex} -vn -c:a copy {outPath.Wrap()}";
|
||||
await RunFfmpeg(args, LogMode.Hidden, "panic");
|
||||
|
||||
if (File.Exists(outPath) && IOUtils.GetFilesize(outPath) < 512)
|
||||
if (IOUtils.GetFilesize(outPath) < 512)
|
||||
{
|
||||
Logger.Log($"Failed to extract audio stream #{track.streamIndex} losslessly! Trying to re-encode.");
|
||||
// Logger.Log($"Failed to extract audio stream #{track.streamIndex} losslessly! Trying to re-encode.");
|
||||
File.Delete(outPath);
|
||||
outPath = Path.ChangeExtension(outPath, Utils.GetAudioExtForContainer(Path.GetExtension(inputFile)));
|
||||
args = $"{trim[0]} -i {inputFile.Wrap()} {trim[1]} -vn {Utils.GetAudioFallbackArgs(Interpolate.current.outMode)} {outPath.Wrap()}";
|
||||
args = $"{trim[0]} -i {inputFile.Wrap()} {trim[1]} -vn {Utils.GetAudioFallbackArgs(I.current.outMode)} {outPath.Wrap()}";
|
||||
await RunFfmpeg(args, LogMode.Hidden, "panic", TaskType.ExtractOther, true);
|
||||
|
||||
if (File.Exists(outPath) && IOUtils.GetFilesize(outPath) < 512)
|
||||
if (IOUtils.GetFilesize(outPath) < 512)
|
||||
{
|
||||
Logger.Log($"Failed to extract audio stream #{track.streamIndex}, even with re-encoding. Will be missing from output.");
|
||||
IOUtils.TryDeleteIfExists(outPath);
|
||||
@@ -73,7 +73,7 @@ namespace Flowframes.Media
|
||||
string line = outputLines[i];
|
||||
if (!line.Contains(" Audio: ")) continue;
|
||||
|
||||
int streamIndex = line.Remove("Stream #0:").Split(':')[0].GetInt();
|
||||
int streamIndex = line.Remove("Stream #0:").Split(':')[0].Split('[')[0].GetInt();
|
||||
|
||||
string meta = "";
|
||||
string codec = "";
|
||||
@@ -171,6 +171,7 @@ namespace Flowframes.Media
|
||||
|
||||
#endregion
|
||||
|
||||
#region Mux From Input
|
||||
public static async Task MergeStreamsFromInput (string inputVideo, string interpVideo, string tempFolder)
|
||||
{
|
||||
if (!File.Exists(inputVideo) && !I.current.inputIsFrames)
|
||||
@@ -188,9 +189,12 @@ namespace Flowframes.Media
|
||||
|
||||
string subArgs = "-c:s " + Utils.GetSubCodecForContainer(containerExt);
|
||||
|
||||
bool audioCompat = Utils.ContainerSupportsAllAudioFormats(I.current.outMode, GetAudioCodecs(interpVideo));
|
||||
bool audioCompat = Utils.ContainerSupportsAllAudioFormats(I.current.outMode, GetAudioCodecs(inputVideo));
|
||||
string audioArgs = audioCompat ? "" : Utils.GetAudioFallbackArgs(I.current.outMode);
|
||||
|
||||
if (!audioCompat)
|
||||
Logger.Log("Warning: Input audio format(s) not fully supported in output container - Will re-encode.", true, false, "ffmpeg");
|
||||
|
||||
bool enableAudio = Config.GetBool("keepAudio");
|
||||
bool enableSubs = Config.GetBool("keepSubs");
|
||||
|
||||
@@ -232,6 +236,10 @@ namespace Flowframes.Media
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Mux From Extracted Streams
|
||||
|
||||
public static async Task MergeAudioAndSubs(string interpVideo, string tempFolder) // https://superuser.com/a/277667
|
||||
{
|
||||
string containerExt = Path.GetExtension(interpVideo);
|
||||
@@ -288,17 +296,17 @@ namespace Flowframes.Media
|
||||
inputIndex++;
|
||||
}
|
||||
|
||||
bool allAudioCodecsSupported = true;
|
||||
bool audioCompat = true;
|
||||
|
||||
foreach (string audioTrack in audioTracks)
|
||||
if (!Utils.ContainerSupportsAudioFormat(I.current.outMode, Path.GetExtension(audioTrack)))
|
||||
allAudioCodecsSupported = false;
|
||||
audioCompat = false;
|
||||
|
||||
if(!allAudioCodecsSupported)
|
||||
Logger.Log("Warning: Input audio format(s) not fully supported in output container. Audio transfer will not be lossless.", false, false, "ffmpeg");
|
||||
if(!audioCompat)
|
||||
Logger.Log("Warning: Input audio format(s) not fully supported in output container - Will re-encode.", true, false, "ffmpeg");
|
||||
|
||||
string subArgs = "-c:s " + Utils.GetSubCodecForContainer(containerExt);
|
||||
string audioArgs = allAudioCodecsSupported ? "-c:a copy" : Utils.GetAudioFallbackArgs(I.current.outMode);
|
||||
string audioArgs = audioCompat ? "-c:a copy" : Utils.GetAudioFallbackArgs(I.current.outMode);
|
||||
|
||||
string args = $" -i {inName} {trackInputArgs} -map 0:v {trackMapArgs} -c:v copy {audioArgs} {subArgs} {trackMetaArgs} {outName}";
|
||||
|
||||
@@ -336,5 +344,7 @@ namespace Flowframes.Media
|
||||
File.Move(tempPath, interpVideo);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,6 +197,7 @@ namespace Flowframes
|
||||
|
||||
public static string GetAudioCodec(string path, int streamIndex = -1)
|
||||
{
|
||||
Logger.Log($"GetAudioCodec('{Path.GetFileName(path)}', {streamIndex})", true, false, "ffmpeg");
|
||||
string stream = (streamIndex < 0) ? "a" : $"{streamIndex}";
|
||||
string args = $"-v panic -show_streams -select_streams {stream} -show_entries stream=codec_name {path.Wrap()}";
|
||||
string info = GetFfprobeOutput(args);
|
||||
@@ -212,6 +213,7 @@ namespace Flowframes
|
||||
|
||||
public static List<string> GetAudioCodecs(string path, int streamIndex = -1)
|
||||
{
|
||||
Logger.Log($"GetAudioCodecs('{Path.GetFileName(path)}', {streamIndex})", true, false, "ffmpeg");
|
||||
List<string> codecNames = new List<string>();
|
||||
string args = $"-loglevel panic -select_streams a -show_entries stream=codec_name {path.Wrap()}";
|
||||
string info = GetFfprobeOutput(args);
|
||||
|
||||
Reference in New Issue
Block a user