mirror of
https://github.com/BililiveRecorder/BililiveRecorder.git
synced 2024-11-16 11:42:22 +08:00
commit
133d3686db
9
.editorconfig
Normal file
9
.editorconfig
Normal file
|
@ -0,0 +1,9 @@
|
|||
# http://editorconfig.org/
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# all files
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -261,5 +261,5 @@ paket-files/
|
|||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
BililiveRecorder.WPF/BuildInfo.cs
|
||||
**/BuildInfo.cs
|
||||
BililiveRecorder.WPF/Nlog.config
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
|
@ -134,11 +133,11 @@ namespace BililiveRecorder.Core
|
|||
var withoutTxy = all.Where(x => !x.Contains("txy.")).ToArray();
|
||||
if (withoutTxy.Length > 0)
|
||||
{
|
||||
return withoutTxy[random.Next(0, withoutTxy.Length - 1)];
|
||||
return withoutTxy[random.Next(withoutTxy.Length)];
|
||||
}
|
||||
else if (attempt_left <= 0)
|
||||
{
|
||||
return all[random.Next(0, all.Length - 1)];
|
||||
return all[random.Next(all.Length)];
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -152,15 +151,11 @@ namespace BililiveRecorder.Core
|
|||
// 随机选择一个 url
|
||||
if ((await HttpGetJsonAsync(url))?["data"]?["durl"] is JArray array)
|
||||
{
|
||||
List<string> urls = new List<string>();
|
||||
for (int i = 0; i < array.Count; i++)
|
||||
{
|
||||
urls.Add(array[i]?["url"]?.ToObject<string>());
|
||||
}
|
||||
var urls = array.Select(t => t?["url"]?.ToObject<string>());
|
||||
var distinct = urls.Distinct().ToArray();
|
||||
if (distinct.Length > 0)
|
||||
{
|
||||
return distinct[random.Next(0, distinct.Count() - 1)];
|
||||
return distinct[random.Next(distinct.Length)];
|
||||
}
|
||||
}
|
||||
throw new Exception("没有直播播放地址");
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
<DebugType>none</DebugType>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BuildInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac" Version="4.8.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||
|
@ -24,4 +27,8 @@
|
|||
<ItemGroup>
|
||||
<ProjectReference Include="..\BililiveRecorder.FlvProcessor\BililiveRecorder.FlvProcessor.csproj" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>cd $(SolutionDir)
|
||||
powershell -ExecutionPolicy Bypass -File .\CI\patch_buildinfo.ps1 Core</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -86,12 +86,6 @@ namespace BililiveRecorder.Core.Config
|
|||
[JsonProperty("timing_watchdog_timeout")]
|
||||
public uint TimingWatchdogTimeout { get => _timingWatchdogTimeout; set => SetField(ref _timingWatchdogTimeout, value); }
|
||||
|
||||
/// <summary>
|
||||
/// 最大直播数据落后时间 毫秒
|
||||
/// </summary>
|
||||
[JsonProperty("timing_watchdog_behind")]
|
||||
public uint TimingWatchdogBehind { get => _timingWatchdogBehind; set => SetField(ref _timingWatchdogBehind, value); }
|
||||
|
||||
/// <summary>
|
||||
/// 请求 API 时使用的 Cookie
|
||||
/// </summary>
|
||||
|
@ -123,7 +117,6 @@ namespace BililiveRecorder.Core.Config
|
|||
private string _workDirectory;
|
||||
|
||||
private uint _timingWatchdogTimeout = 10 * 1000;
|
||||
private uint _timingWatchdogBehind = 10 * 1000;
|
||||
private uint _timingStreamRetry = 6 * 1000;
|
||||
private uint _timingStreamConnect = 3 * 1000;
|
||||
private uint _timingDanmakuRetry = 2 * 1000;
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace BililiveRecorder.Core
|
|||
bool IsRecording { get; }
|
||||
|
||||
double DownloadSpeedPersentage { get; }
|
||||
double DownloadSpeedKiBps { get; }
|
||||
double DownloadSpeedMegaBitps { get; }
|
||||
DateTime LastUpdateDateTime { get; }
|
||||
|
||||
void Clip();
|
||||
|
|
|
@ -82,7 +82,7 @@ namespace BililiveRecorder.Core
|
|||
public CancellationTokenSource cancellationTokenSource = null;
|
||||
|
||||
private double _DownloadSpeedPersentage = 0;
|
||||
private double _DownloadSpeedKiBps = 0;
|
||||
private double _DownloadSpeedMegaBitps = 0;
|
||||
private long _lastUpdateSize = 0;
|
||||
private int _lastUpdateTimestamp = 0;
|
||||
public DateTime LastUpdateDateTime { get; private set; } = DateTime.Now;
|
||||
|
@ -91,10 +91,10 @@ namespace BililiveRecorder.Core
|
|||
get { return _DownloadSpeedPersentage; }
|
||||
private set { if (value != _DownloadSpeedPersentage) { _DownloadSpeedPersentage = value; TriggerPropertyChanged(nameof(DownloadSpeedPersentage)); } }
|
||||
}
|
||||
public double DownloadSpeedKiBps
|
||||
public double DownloadSpeedMegaBitps
|
||||
{
|
||||
get { return _DownloadSpeedKiBps; }
|
||||
private set { if (value != _DownloadSpeedKiBps) { _DownloadSpeedKiBps = value; TriggerPropertyChanged(nameof(DownloadSpeedKiBps)); } }
|
||||
get { return _DownloadSpeedMegaBitps; }
|
||||
private set { if (value != _DownloadSpeedMegaBitps) { _DownloadSpeedMegaBitps = value; TriggerPropertyChanged(nameof(DownloadSpeedMegaBitps)); } }
|
||||
}
|
||||
|
||||
public RecordedRoom(ConfigV1 config,
|
||||
|
@ -192,7 +192,7 @@ namespace BililiveRecorder.Core
|
|||
cancellationTokenSource.Cancel();
|
||||
if (!(StreamDownloadTask?.Wait(TimeSpan.FromSeconds(2)) ?? true))
|
||||
{
|
||||
logger.Log(RoomId, LogLevel.Warn, "尝试强制关闭连接,请检查网络连接是否稳定");
|
||||
logger.Log(RoomId, LogLevel.Warn, "停止录制超时,尝试强制关闭连接,请检查网络连接是否稳定");
|
||||
|
||||
_stream?.Close();
|
||||
_stream?.Dispose();
|
||||
|
@ -283,7 +283,7 @@ namespace BililiveRecorder.Core
|
|||
},
|
||||
{
|
||||
"version",
|
||||
"TEST"
|
||||
BuildInfo.Version + " " + BuildInfo.HeadShaShort
|
||||
},
|
||||
{
|
||||
"roomid",
|
||||
|
@ -351,7 +351,7 @@ namespace BililiveRecorder.Core
|
|||
}
|
||||
|
||||
logger.Log(RoomId, LogLevel.Info,
|
||||
(token.IsCancellationRequested ? "用户操作" : "直播已结束") + ",停止录制。"
|
||||
(token.IsCancellationRequested ? "本地操作结束当前录制。" : "服务器关闭直播流,可能是直播已结束。")
|
||||
+ (_retry ? "将重试启动。" : ""));
|
||||
if (_retry)
|
||||
{
|
||||
|
@ -383,7 +383,7 @@ namespace BililiveRecorder.Core
|
|||
_response = null;
|
||||
|
||||
_lastUpdateTimestamp = 0;
|
||||
DownloadSpeedKiBps = 0d;
|
||||
DownloadSpeedMegaBitps = 0d;
|
||||
DownloadSpeedPersentage = 0d;
|
||||
TriggerPropertyChanged(nameof(IsRecording));
|
||||
}
|
||||
|
@ -394,7 +394,7 @@ namespace BililiveRecorder.Core
|
|||
_lastUpdateSize += bytesRead;
|
||||
if (passedSeconds > 1.5)
|
||||
{
|
||||
DownloadSpeedKiBps = _lastUpdateSize / passedSeconds / 1024; // KiB per sec
|
||||
DownloadSpeedMegaBitps = _lastUpdateSize / passedSeconds * 8d / 1_000_000d; // mega bit per second
|
||||
DownloadSpeedPersentage = (DownloadSpeedPersentage / 2) + ((Processor.TotalMaxTimestamp - _lastUpdateTimestamp) / passedSeconds / 1000 / 2); // ((RecordedTime/1000) / RealTime)%
|
||||
_lastUpdateTimestamp = Processor.TotalMaxTimestamp;
|
||||
_lastUpdateSize = 0;
|
||||
|
|
|
@ -213,17 +213,7 @@ namespace BililiveRecorder.Core
|
|||
{
|
||||
if (DateTime.Now - room.LastUpdateDateTime > TimeSpan.FromMilliseconds(Config.TimingWatchdogTimeout))
|
||||
{
|
||||
logger.Warn("服务器停止提供 [{roomid}] 直播间的直播数据,通常是录制时网络不稳定导致,将会断开重连", room.RoomId);
|
||||
room.StopRecord();
|
||||
room.StartRecord();
|
||||
}
|
||||
else if (room.Processor != null &&
|
||||
((DateTime.Now - room.Processor.StartDateTime).TotalMilliseconds
|
||||
>
|
||||
(room.Processor.TotalMaxTimestamp + Config.TimingWatchdogBehind))
|
||||
)
|
||||
{
|
||||
logger.Warn("直播间 [{roomid}] 的下载速度达不到录制标准,将断开重连。请检查网络是否稳定", room.RoomId);
|
||||
logger.Warn("服务器未断开连接但停止提供 [{roomid}] 直播间的直播数据,通常是录制侧网络不稳定导致,将会断开重连", room.RoomId);
|
||||
room.StopRecord();
|
||||
room.StartRecord();
|
||||
}
|
||||
|
|
|
@ -16,8 +16,15 @@
|
|||
<DebugType>none</DebugType>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BuildInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac" Version="4.8.1" />
|
||||
<PackageReference Include="NLog" Version="4.5.10" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>cd $(SolutionDir)
|
||||
powershell -ExecutionPolicy Bypass -File .\CI\patch_buildinfo.ps1 FlvProcessor</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -249,7 +249,7 @@ namespace BililiveRecorder.FlvProcessor
|
|||
{
|
||||
if (_hasOffset)
|
||||
{
|
||||
tag.SetTimeStamp(Math.Max(0, tag.TimeStamp - _baseTimeStamp)); // 修复时间戳
|
||||
tag.SetTimeStamp(tag.TimeStamp - _baseTimeStamp);
|
||||
TotalMaxTimestamp = Math.Max(TotalMaxTimestamp, tag.TimeStamp);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -77,8 +77,7 @@ namespace BililiveRecorder.FlvProcessor
|
|||
var size = BitConverter.GetBytes(useDataSize ? Data.Length : TagSize).ToBE();
|
||||
Buffer.BlockCopy(size, 1, tag, 1, 3);
|
||||
|
||||
byte[] timing = new byte[4];
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(Math.Max(0, TimeStamp - offset)).ToBE(), 0, timing, 0, timing.Length);
|
||||
byte[] timing = BitConverter.GetBytes(TimeStamp - offset).ToBE();
|
||||
Buffer.BlockCopy(timing, 1, tag, 4, 3);
|
||||
Buffer.BlockCopy(timing, 0, tag, 7, 1);
|
||||
|
||||
|
|
|
@ -196,7 +196,6 @@
|
|||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<None Include="BuildInfo.txt" />
|
||||
<None Include="Properties\app.manifest" />
|
||||
<Resource Include="ico.ico" />
|
||||
<Content Include="NLog.config">
|
||||
|
@ -225,7 +224,7 @@
|
|||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>cd $(SolutionDir)
|
||||
PowerShell -ExecutionPolicy Bypass -File .\CI\patch_buildinfo.ps1
|
||||
powershell -ExecutionPolicy Bypass -File .\CI\patch_buildinfo.ps1 WPF
|
||||
copy /y .\BililiveRecorder.WPF\Nlog.$(ConfigurationName).config .\BililiveRecorder.WPF\NLog.config</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
|
|
|
@ -95,7 +95,7 @@
|
|||
<DataGridTextColumn Binding="{Binding StreamerName,Mode=OneWay}" Header="主播名字"/>
|
||||
<DataGridTextColumn Binding="{Binding IsRecording,Converter={StaticResource RecordStatusConverter},Mode=OneWay}" Header="录制状态"/>
|
||||
<DataGridTextColumn Binding="{Binding IsMonitoring,Converter={StaticResource MonitorStatusConverter},Mode=OneWay}" Header="是否自动录制"/>
|
||||
<DataGridTextColumn Binding="{Binding DownloadSpeedKiBps,StringFormat=0.## KiB/s,Mode=OneWay}" Header="录制下载速度"/>
|
||||
<DataGridTextColumn Binding="{Binding DownloadSpeedMegaBitps,StringFormat=0.## Mbps,Mode=OneWay}" Header="实时下载速度"/>
|
||||
<DataGridTextColumn Binding="{Binding DownloadSpeedPersentage,StringFormat=0.## %,Mode=OneWay}" Header="录制速度比"/>
|
||||
<DataGridTextColumn Binding="{Binding Processor.Clips.Count,Mode=OneWay}" Header="剪辑数量"/>
|
||||
</DataGrid.Columns>
|
||||
|
@ -156,8 +156,8 @@
|
|||
<TextBlock Grid.Row="5" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right">处理中剪辑数量:</TextBlock>
|
||||
<TextBlock Grid.Row="5" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" Text="{Binding Processor.Clips.Count,Mode=OneWay}"/>
|
||||
|
||||
<TextBlock Grid.Row="6" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right">录制下载速度:</TextBlock>
|
||||
<TextBlock Grid.Row="6" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" Text="{Binding DownloadSpeedKiBps,StringFormat=0.## KiB/s,Mode=OneWay}"/>
|
||||
<TextBlock Grid.Row="6" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right">实时下载速度:</TextBlock>
|
||||
<TextBlock Grid.Row="6" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" Text="{Binding DownloadSpeedMegaBitps,StringFormat=0.## Mbps,Mode=OneWay}"/>
|
||||
|
||||
<TextBlock Grid.Row="7" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right">录制速度比:</TextBlock>
|
||||
<TextBlock Grid.Row="7" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" Text="{Binding DownloadSpeedPersentage,StringFormat=0.## %,Mode=OneWay}"/>
|
||||
|
|
|
@ -39,7 +39,10 @@ namespace BililiveRecorder.WPF
|
|||
"问题反馈邮箱: rec@danmuji.org",
|
||||
"QQ群: 689636812",
|
||||
"",
|
||||
"功能调整:删除直播间按钮调整了位置,从软件界面右侧移动到了列表右键菜单"
|
||||
"删除直播间按钮在列表右键菜单里",
|
||||
"",
|
||||
"录制速度比 在 100% 左右说明跟上了主播直播的速度",
|
||||
"小于 100% 说明录播电脑的下载带宽不够,跟不上录制直播"
|
||||
};
|
||||
|
||||
public static void AddLog(string message) => _AddLog?.Invoke(message);
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
<ColumnDefinition Width="2*"/>
|
||||
<ColumnDefinition Width="3*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Row="0" Grid.Column="0">录制重连间隔:</TextBlock>
|
||||
<TextBlock Grid.Row="0" Grid.Column="0">录制重试间隔:</TextBlock>
|
||||
<Grid Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="1*"/>
|
||||
|
@ -130,7 +130,7 @@
|
|||
</local:ClickSelectTextBox>
|
||||
<TextBlock Grid.Column="1" Margin="5,0,10,0">毫秒</TextBlock>
|
||||
</Grid>
|
||||
<TextBlock Grid.Row="3" Grid.Column="0">录制超时时间:</TextBlock>
|
||||
<TextBlock Grid.Row="3" Grid.Column="0">接收数据超时:</TextBlock>
|
||||
<Grid Grid.Row="3" Grid.Column="1" VerticalAlignment="Center">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="1*"/>
|
||||
|
@ -154,31 +154,6 @@
|
|||
</local:ClickSelectTextBox>
|
||||
<TextBlock Grid.Column="1" Margin="5,0,10,0">毫秒</TextBlock>
|
||||
</Grid>
|
||||
<TextBlock Grid.Row="4" Grid.Column="0">录制最长落后:</TextBlock>
|
||||
<Grid Grid.Row="4" Grid.Column="1" VerticalAlignment="Center">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="1*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<local:ClickSelectTextBox Grid.Column="0" Text="{Binding TimingWatchdogBehind,Delay=500,UpdateSourceTrigger=PropertyChanged}">
|
||||
<local:ClickSelectTextBox.ToolTip>
|
||||
<ToolTip>
|
||||
<StackPanel>
|
||||
<StackPanel.Resources>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="TextAlignment" Value="Left"/>
|
||||
</Style>
|
||||
</StackPanel.Resources>
|
||||
<TextBlock FontWeight="Bold">注:</TextBlock>
|
||||
<TextBlock>录制比主播直播落后一定时间后自动断开重连。</TextBlock>
|
||||
<TextBlock>实际使用中如果发生了因为跟不上主播直播</TextBlock>
|
||||
<TextBlock>的情况,说明录制电脑的网速不够。</TextBlock>
|
||||
</StackPanel>
|
||||
</ToolTip>
|
||||
</local:ClickSelectTextBox.ToolTip>
|
||||
</local:ClickSelectTextBox>
|
||||
<TextBlock Grid.Column="1" Margin="5,0,10,0">毫秒</TextBlock>
|
||||
</Grid>
|
||||
<TextBlock Grid.Row="5" Grid.Column="0">开播检查间隔:</TextBlock>
|
||||
<Grid Grid.Row="5" Grid.Column="1" VerticalAlignment="Center">
|
||||
<Grid.ColumnDefinitions>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace BililiveRecorder.WPF
|
||||
namespace BililiveRecorder.[PROJECT_NAME]
|
||||
{
|
||||
internal class BuildInfo
|
||||
{
|
|
@ -4,4 +4,6 @@ $isAppveyor = if ($env:APPVEYOR -eq $null) { "false" } else { $env:APPVEYOR }
|
|||
$buildversion = if ($env:APPVEYOR_BUILD_VERSION -eq $null) { "本地编译" } else { $env:APPVEYOR_BUILD_VERSION }
|
||||
$githash = git rev-parse --verify HEAD
|
||||
|
||||
(Get-Content .\BililiveRecorder.WPF\BuildInfo.txt).Replace('[APPVEYOR]', $isAppveyor.ToLower()).Replace('[VERSION]', $buildversion).Replace('[GIT_HASH]', $githash).Replace('[GIT_HASH_S]', $githash.Substring(0, 8)) | Set-Content .\BililiveRecorder.WPF\BuildInfo.cs
|
||||
(Get-Content .\BuildInfo.txt).Replace('[PROJECT_NAME]', $args).Replace('[APPVEYOR]', $isAppveyor.ToLower()).Replace('[VERSION]', $buildversion).Replace('[GIT_HASH]', $githash).Replace('[GIT_HASH_S]', $githash.Substring(0, 8)) | Set-Content ".\BililiveRecorder.$args\BuildInfo.cs"
|
||||
|
||||
Write-Output "BuildInfo for $args patched"
|
||||
|
|
17
README.md
17
README.md
|
@ -19,19 +19,16 @@ See [rec.danmuji.org](https://rec.danmuji.org) (in Chinese)
|
|||
## Feature
|
||||
|
||||
- Easy to use
|
||||
- Fix timestamp automatically
|
||||
- Reset timestamp to start from 0
|
||||
- Writes duration info automatically when recoding session ends.
|
||||
- Start recording when stream starts
|
||||
- Record multiple stream at same time
|
||||
- Have a "Clip" Feature (just like [Twitch's](https://help.twitch.tv/customer/portal/articles/2442508-how-to-use-clips))
|
||||
- Pure C#, no native dependents
|
||||
- Pure C#, no native dependency like ffmpeg
|
||||
- Open source!
|
||||
|
||||
## Develop & Getting Started
|
||||
|
||||
You'll need:
|
||||
|
||||
- Visual Studio 2017 with .NET Core
|
||||
- PowerShell
|
||||
**Visual Studio 2017 with .NET Core** and **PowerShell** is required. Visual Studio 2019 *could* work but is not tested.
|
||||
|
||||
Some file are generated by [PreComplie Script](./CI/patch_buildinfo.ps1). Build project to clear errors shown by Visual Studio.
|
||||
|
||||
|
@ -50,6 +47,6 @@ You can start poking around from...
|
|||
|
||||
## Reference & Acknowledgements
|
||||
|
||||
- [coreyauger/flv-streamer-2-file](https://github.com/coreyauger/flv-streamer-2-file): An awesome library.
|
||||
- [zyzsdy/biliroku](https://github.com/zyzsdy/biliroku): First BiliBili stream record tool.
|
||||
- [Video File Format Specification Version 10.pdf](https://wwwimages2.adobe.com/content/dam/acom/en/devnet/flv/video_file_format_spec_v10.pdf)
|
||||
- [Adobe Flash Video File Format Specification 10.1.2.01.pdf](https://www.adobe.com/content/dam/acom/en/devnet/flv/video_file_format_spec_v10_1.pdf)
|
||||
- [coreyauger/flv-streamer-2-file](https://github.com/coreyauger/flv-streamer-2-file)
|
||||
- [zyzsdy/biliroku](https://github.com/zyzsdy/biliroku) - (probably) first BiliBili stream recording tool.
|
||||
|
|
20
README_CN.md
20
README_CN.md
|
@ -13,11 +13,11 @@
|
|||
## 功能
|
||||
|
||||
- 使用简单
|
||||
- 自动修复视频时间戳
|
||||
- 使录出的文件时间戳从 0 开始
|
||||
- 录制结束后自动写入总时长信息
|
||||
- 可以主播开播后自动录制
|
||||
- 可以同时录制多个直播间
|
||||
- 可以录制“即时回放剪辑”(类似 [Twitch 的 Clip](https://help.twitch.tv/customer/portal/articles/2442508-how-to-use-clips))
|
||||
- 纯 C# 实现,无 Native 依赖
|
||||
- 纯 C# 实现,无 ffmpeg 等 native 依赖
|
||||
- 开源!
|
||||
|
||||
## 入门 & 开发
|
||||
|
@ -34,7 +34,7 @@
|
|||
BililiveRecorder.WPF | .NET Framework 4.6.2
|
||||
BililiveRecorder.Core | .NET Standard 2.0
|
||||
BililiveRecorder.FlvProcessor | .NET Standard 2.0
|
||||
BililiveRecorder.Server | .NET Core 2.0 | 预留坑,将来填
|
||||
BililiveRecorder.Server | .NET Core 2.0 | 预留坑,将来填(咕咕咕)
|
||||
|
||||
如果你想研究这个项目的源代码,或修改功能的话:
|
||||
|
||||
|
@ -42,8 +42,14 @@ BililiveRecorder.Server | .NET Core 2.0 | 预留坑,将来填
|
|||
- 录制逻辑建议从 `BililiveRecorder.Core/Recorder.cs` 开始看
|
||||
- FLV数据处理建议从 `BililiveRecorder.FlvProcessor/FlvStreamProcessor.cs` 开始看
|
||||
|
||||
## Server 版说明
|
||||
|
||||
本项目核心逻辑均与 WPF 界面分离,使用 .NET Standard 2.0 而不是 .NET Framework,可以较轻松地改出可在 Linux 上运行的 .NET Core 版本,但因为本人没时间等原因一直没有做。
|
||||
|
||||
如果有有能人士有在 Linux 上运行本项目的需求的话可以自行 fork 修改(但我大概不会 merge 回来)
|
||||
|
||||
## 参考资料 & 鸣谢
|
||||
|
||||
- [coreyauger/flv-streamer-2-file](https://github.com/coreyauger/flv-streamer-2-file): 在FLV处理方面参考了很多
|
||||
- [zyzsdy/biliroku](https://github.com/zyzsdy/biliroku): 第一个B站直播录播工具
|
||||
- [Video File Format Specification Version 10.pdf](https://wwwimages2.adobe.com/content/dam/acom/en/devnet/flv/video_file_format_spec_v10.pdf): FLV视频文件格式规范
|
||||
- [Adobe Flash Video File Format Specification 10.1.2.01.pdf](https://www.adobe.com/content/dam/acom/en/devnet/flv/video_file_format_spec_v10_1.pdf)
|
||||
- [coreyauger/flv-streamer-2-file](https://github.com/coreyauger/flv-streamer-2-file)
|
||||
- [zyzsdy/biliroku](https://github.com/zyzsdy/biliroku): (大概是)第一个B站直播录播工具
|
||||
|
|
|
@ -34,10 +34,10 @@ install:
|
|||
|
||||
before_build:
|
||||
- nuget restore -Verbosity quiet
|
||||
- msbuild /nologo /v:q /t:Clean
|
||||
- msbuild /nologo /v:m /t:Clean
|
||||
|
||||
build_script:
|
||||
- ps: msbuild /nologo /v:q /p:Configuration="$env:CONFIGURATION" /p:SquirrelBuildTarget="$env:DEPLOY_SITE_GIT\BililiveRecorder" /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||
- ps: msbuild /nologo /v:m /p:Configuration="$env:CONFIGURATION" /p:SquirrelBuildTarget="$env:DEPLOY_SITE_GIT\BililiveRecorder" /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||
|
||||
for:
|
||||
-
|
||||
|
|
Loading…
Reference in New Issue
Block a user