mirror of
https://github.com/BililiveRecorder/BililiveRecorder.git
synced 2024-11-15 19:22:19 +08:00
fix(flv): stop recording on unsupported codec
This commit is contained in:
parent
07a203d46d
commit
1e8bab25d6
|
@ -12,6 +12,7 @@ using BililiveRecorder.Core.ProcessingRules;
|
||||||
using BililiveRecorder.Core.Scripting;
|
using BililiveRecorder.Core.Scripting;
|
||||||
using BililiveRecorder.Flv;
|
using BililiveRecorder.Flv;
|
||||||
using BililiveRecorder.Flv.Amf;
|
using BililiveRecorder.Flv.Amf;
|
||||||
|
using BililiveRecorder.Flv.Parser;
|
||||||
using BililiveRecorder.Flv.Pipeline;
|
using BililiveRecorder.Flv.Pipeline;
|
||||||
using BililiveRecorder.Flv.Pipeline.Actions;
|
using BililiveRecorder.Flv.Pipeline.Actions;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
@ -134,7 +135,7 @@ namespace BililiveRecorder.Core.Recording
|
||||||
if (bytesRead == 0)
|
if (bytesRead == 0)
|
||||||
break;
|
break;
|
||||||
writer.Advance(bytesRead);
|
writer.Advance(bytesRead);
|
||||||
Interlocked.Add(ref this.ioNetworkDownloadedBytes, bytesRead);
|
_ = Interlocked.Add(ref this.ioNetworkDownloadedBytes, bytesRead);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -194,6 +195,12 @@ namespace BililiveRecorder.Core.Recording
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (UnsupportedCodecException ex)
|
||||||
|
{
|
||||||
|
// 直播流不是 H.264
|
||||||
|
this.logger.Warning(ex, "不支持此直播流的视频编码格式(只支持 H.264),本场直播不再自动启动录制。");
|
||||||
|
this.room.StopRecord(); // 停止自动重试
|
||||||
|
}
|
||||||
catch (OperationCanceledException ex)
|
catch (OperationCanceledException ex)
|
||||||
{
|
{
|
||||||
this.logger.Debug(ex, "录制被取消");
|
this.logger.Debug(ex, "录制被取消");
|
||||||
|
@ -260,7 +267,7 @@ namespace BililiveRecorder.Core.Recording
|
||||||
switch (this.room.RoomConfig.CuttingMode)
|
switch (this.room.RoomConfig.CuttingMode)
|
||||||
{
|
{
|
||||||
case CuttingMode.ByTime:
|
case CuttingMode.ByTime:
|
||||||
if (e.FileMaxTimestamp > this.room.RoomConfig.CuttingNumber * (60u * 1000u))
|
if (e.FileMaxTimestamp > this.room.RoomConfig.CuttingNumber * 60u * 1000u)
|
||||||
this.splitFileRule.SetSplitBeforeFlag();
|
this.splitFileRule.SetSplitBeforeFlag();
|
||||||
break;
|
break;
|
||||||
case CuttingMode.BySize:
|
case CuttingMode.BySize:
|
||||||
|
@ -290,7 +297,7 @@ namespace BililiveRecorder.Core.Recording
|
||||||
var paths = this.task.CreateFileName();
|
var paths = this.task.CreateFileName();
|
||||||
|
|
||||||
try
|
try
|
||||||
{ Directory.CreateDirectory(Path.GetDirectoryName(paths.fullPath)); }
|
{ _ = Directory.CreateDirectory(Path.GetDirectoryName(paths.fullPath)); }
|
||||||
catch (Exception) { }
|
catch (Exception) { }
|
||||||
|
|
||||||
this.last_path = paths.fullPath;
|
this.last_path = paths.fullPath;
|
||||||
|
@ -307,7 +314,7 @@ namespace BililiveRecorder.Core.Recording
|
||||||
: Path.ChangeExtension(this.last_path, "txt");
|
: Path.ChangeExtension(this.last_path, "txt");
|
||||||
|
|
||||||
try
|
try
|
||||||
{ Directory.CreateDirectory(Path.GetDirectoryName(path)); }
|
{ _ = Directory.CreateDirectory(Path.GetDirectoryName(path)); }
|
||||||
catch (Exception) { }
|
catch (Exception) { }
|
||||||
|
|
||||||
var stream = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Read);
|
var stream = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Read);
|
||||||
|
|
|
@ -317,7 +317,7 @@ namespace BililiveRecorder.Core
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
this.recordRetryDelaySemaphoreSlim.Release();
|
_ = this.recordRetryDelaySemaphoreSlim.Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果状态是非直播中,跳过重试尝试。当状态切换到直播中时会开始新的录制任务。
|
// 如果状态是非直播中,跳过重试尝试。当状态切换到直播中时会开始新的录制任务。
|
||||||
|
@ -451,7 +451,7 @@ namespace BililiveRecorder.Core
|
||||||
{
|
{
|
||||||
const int MAX_ATTEMPT = 3;
|
const int MAX_ATTEMPT = 3;
|
||||||
var attempt = 0;
|
var attempt = 0;
|
||||||
retry:
|
retry:
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var coverUrl = this.RawBilibiliApiJsonData?["room_info"]?["cover"]?.ToObject<string>();
|
var coverUrl = this.RawBilibiliApiJsonData?["room_info"]?["cover"]?.ToObject<string>();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
|
||||||
namespace BililiveRecorder.Flv.Parser
|
namespace BililiveRecorder.Flv.Parser
|
||||||
|
@ -14,4 +14,28 @@ namespace BililiveRecorder.Flv.Parser
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
protected FlvException(SerializationInfo info, StreamingContext context) : base(info, context) { }
|
protected FlvException(SerializationInfo info, StreamingContext context) : base(info, context) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class UnknownFlvTagTypeException : FlvException
|
||||||
|
{
|
||||||
|
public UnknownFlvTagTypeException() { }
|
||||||
|
public UnknownFlvTagTypeException(string message) : base(message) { }
|
||||||
|
public UnknownFlvTagTypeException(string message, Exception innerException) : base(message, innerException) { }
|
||||||
|
protected UnknownFlvTagTypeException(SerializationInfo info, StreamingContext context) : base(info, context) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NotFlvFileException : FlvException
|
||||||
|
{
|
||||||
|
public NotFlvFileException() { }
|
||||||
|
public NotFlvFileException(string message) : base(message) { }
|
||||||
|
public NotFlvFileException(string message, Exception innerException) : base(message, innerException) { }
|
||||||
|
protected NotFlvFileException(SerializationInfo info, StreamingContext context) : base(info, context) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UnsupportedCodecException : FlvException
|
||||||
|
{
|
||||||
|
public UnsupportedCodecException() { }
|
||||||
|
public UnsupportedCodecException(string message) : base(message) { }
|
||||||
|
public UnsupportedCodecException(string message, Exception innerException) : base(message, innerException) { }
|
||||||
|
protected UnsupportedCodecException(SerializationInfo info, StreamingContext context) : base(info, context) { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,7 +227,7 @@ namespace BililiveRecorder.Flv.Parser
|
||||||
|
|
||||||
if (tagBodyStream.Length > 2)
|
if (tagBodyStream.Length > 2)
|
||||||
{
|
{
|
||||||
tagBodyStream.Seek(0, SeekOrigin.Begin);
|
_ = tagBodyStream.Seek(0, SeekOrigin.Begin);
|
||||||
switch (tagType)
|
switch (tagType)
|
||||||
{
|
{
|
||||||
case TagType.Audio:
|
case TagType.Audio:
|
||||||
|
@ -243,8 +243,10 @@ namespace BililiveRecorder.Flv.Parser
|
||||||
case TagType.Video:
|
case TagType.Video:
|
||||||
{
|
{
|
||||||
var frame = tagBodyStream.ReadByte();
|
var frame = tagBodyStream.ReadByte();
|
||||||
|
|
||||||
if ((frame & 0x0F) != 7) // AVC
|
if ((frame & 0x0F) != 7) // AVC
|
||||||
break;
|
throw new UnsupportedCodecException(string.Format("Unsupported Video Codec: {0}.", frame & 0x0F));
|
||||||
|
|
||||||
if (frame == 0x17)
|
if (frame == 0x17)
|
||||||
tagFlag |= TagFlag.Keyframe;
|
tagFlag |= TagFlag.Keyframe;
|
||||||
var packet = tagBodyStream.ReadByte();
|
var packet = tagBodyStream.ReadByte();
|
||||||
|
@ -272,7 +274,7 @@ namespace BililiveRecorder.Flv.Parser
|
||||||
};
|
};
|
||||||
|
|
||||||
// Read Tag Type Specific Data
|
// Read Tag Type Specific Data
|
||||||
tagBodyStream.Seek(0, SeekOrigin.Begin);
|
_ = tagBodyStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
if (tag.Type == TagType.Script)
|
if (tag.Type == TagType.Script)
|
||||||
{
|
{
|
||||||
|
@ -320,7 +322,7 @@ namespace BililiveRecorder.Flv.Parser
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
this.peekSemaphoreSlim.Release();
|
_ = this.peekSemaphoreSlim.Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,7 +346,7 @@ namespace BililiveRecorder.Flv.Parser
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
this.peekSemaphoreSlim.Release();
|
_ = this.peekSemaphoreSlim.Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Runtime.Serialization;
|
|
||||||
|
|
||||||
namespace BililiveRecorder.Flv.Parser
|
|
||||||
{
|
|
||||||
public class NotFlvFileException : FlvException
|
|
||||||
{
|
|
||||||
public NotFlvFileException() { }
|
|
||||||
|
|
||||||
public NotFlvFileException(string message) : base(message) { }
|
|
||||||
|
|
||||||
public NotFlvFileException(string message, Exception innerException) : base(message, innerException) { }
|
|
||||||
|
|
||||||
protected NotFlvFileException(SerializationInfo info, StreamingContext context) : base(info, context) { }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Runtime.Serialization;
|
|
||||||
|
|
||||||
namespace BililiveRecorder.Flv.Parser
|
|
||||||
{
|
|
||||||
public class UnknownFlvTagTypeException : FlvException
|
|
||||||
{
|
|
||||||
public UnknownFlvTagTypeException() { }
|
|
||||||
|
|
||||||
public UnknownFlvTagTypeException(string message) : base(message) { }
|
|
||||||
|
|
||||||
public UnknownFlvTagTypeException(string message, Exception innerException) : base(message, innerException) { }
|
|
||||||
|
|
||||||
protected UnknownFlvTagTypeException(SerializationInfo info, StreamingContext context) : base(info, context) { }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -81,8 +81,8 @@ namespace BililiveRecorder.Flv
|
||||||
if (this.BinaryData != null)
|
if (this.BinaryData != null)
|
||||||
{
|
{
|
||||||
binaryData = provider?.CreateMemoryStream(nameof(Tag) + ":" + nameof(Clone)) ?? new MemoryStream();
|
binaryData = provider?.CreateMemoryStream(nameof(Tag) + ":" + nameof(Clone)) ?? new MemoryStream();
|
||||||
this.BinaryData.Seek(0, SeekOrigin.Begin);
|
_ = this.BinaryData.Seek(0, SeekOrigin.Begin);
|
||||||
this.BinaryData.CopyToAsync(binaryData);
|
_ = this.BinaryData.CopyToAsync(binaryData);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptTagBody? scriptData = null;
|
ScriptTagBody? scriptData = null;
|
||||||
|
@ -90,7 +90,7 @@ namespace BililiveRecorder.Flv
|
||||||
{
|
{
|
||||||
using var stream = provider?.CreateMemoryStream(nameof(Tag) + ":" + nameof(Clone) + ":Temp") ?? new MemoryStream();
|
using var stream = provider?.CreateMemoryStream(nameof(Tag) + ":" + nameof(Clone) + ":Temp") ?? new MemoryStream();
|
||||||
this.ScriptData.WriteTo(stream);
|
this.ScriptData.WriteTo(stream);
|
||||||
stream.Seek(0, SeekOrigin.Begin);
|
_ = stream.Seek(0, SeekOrigin.Begin);
|
||||||
scriptData = ScriptTagBody.Parse(stream);
|
scriptData = ScriptTagBody.Parse(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ namespace BililiveRecorder.Flv
|
||||||
var buffer = ArrayPool<byte>.Shared.Rent(5);
|
var buffer = ArrayPool<byte>.Shared.Rent(5);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
binaryData.Read(buffer, 0, 5);
|
_ = binaryData.Read(buffer, 0, 5);
|
||||||
extra.FirstBytes = BinaryConvertUtilities.ByteArrayToHexString(buffer, 0, 2);
|
extra.FirstBytes = BinaryConvertUtilities.ByteArrayToHexString(buffer, 0, 2);
|
||||||
|
|
||||||
if (this.Type == TagType.Video)
|
if (this.Type == TagType.Video)
|
||||||
|
@ -176,14 +176,9 @@ namespace BililiveRecorder.Flv
|
||||||
{
|
{
|
||||||
var bytesLeft = buffer.Length - nalu.StartPosition;
|
var bytesLeft = buffer.Length - nalu.StartPosition;
|
||||||
|
|
||||||
if (bytesLeft >= nalu.FullSize)
|
nalu.NaluHash = bytesLeft >= nalu.FullSize
|
||||||
{
|
? BinaryConvertUtilities.ByteArrayToHexString(farmHash64.ComputeHash(buffer, nalu.StartPosition, (int)nalu.FullSize))
|
||||||
nalu.NaluHash = BinaryConvertUtilities.ByteArrayToHexString(farmHash64.ComputeHash(buffer, nalu.StartPosition, (int)nalu.FullSize));
|
: BinaryConvertUtilities.ByteArrayToHexString(farmHash64.ComputeHash(buffer, nalu.StartPosition, Math.Min(buffer.Length - nalu.StartPosition, (int)nalu.FullSize))) + "-PARTIAL";
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nalu.NaluHash = BinaryConvertUtilities.ByteArrayToHexString(farmHash64.ComputeHash(buffer, nalu.StartPosition, Math.Min(buffer.Length - nalu.StartPosition, (int)nalu.FullSize))) + "-PARTIAL";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,7 +224,7 @@ namespace BililiveRecorder.Flv
|
||||||
{
|
{
|
||||||
var val = lookup32[bytes[i]];
|
var val = lookup32[bytes[i]];
|
||||||
result[2 * i] = (char)val;
|
result[2 * i] = (char)val;
|
||||||
result[2 * i + 1] = (char)(val >> 16);
|
result[(2 * i) + 1] = (char)(val >> 16);
|
||||||
}
|
}
|
||||||
return new string(result);
|
return new string(result);
|
||||||
}
|
}
|
||||||
|
@ -245,13 +240,13 @@ namespace BililiveRecorder.Flv
|
||||||
internal static string StreamToHexString(Stream stream)
|
internal static string StreamToHexString(Stream stream)
|
||||||
{
|
{
|
||||||
var lookup32 = _lookup32;
|
var lookup32 = _lookup32;
|
||||||
stream.Seek(0, SeekOrigin.Begin);
|
_ = stream.Seek(0, SeekOrigin.Begin);
|
||||||
var result = new char[stream.Length * 2];
|
var result = new char[stream.Length * 2];
|
||||||
for (var i = 0; i < stream.Length; i++)
|
for (var i = 0; i < stream.Length; i++)
|
||||||
{
|
{
|
||||||
var val = lookup32[stream.ReadByte()];
|
var val = lookup32[stream.ReadByte()];
|
||||||
result[2 * i] = (char)val;
|
result[2 * i] = (char)val;
|
||||||
result[2 * i + 1] = (char)(val >> 16);
|
result[(2 * i) + 1] = (char)(val >> 16);
|
||||||
}
|
}
|
||||||
return new string(result);
|
return new string(result);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user