解释:.dpl
主要为Potplayer
直播源列表文件
文件格式
文件头
playname
为当前播放的地址
topindex
为当前播放的序号,即在列表中的位置
列表项
序号从 1
开始
地址行为 序号 + *file*
+ 地址
标题行为 序号 + *title*
+ 地址
txt 文件转 dpl
txt 文件每一行格式为
- 获取文件编码
- 移动到正文开始的位置
- 写入文件头
- 循环取每一行,转换并写入
具体转换代码
const string HEADER_TAG = "DAUMPLAYLIST";
const string FILE_TAG = "*file*";
const string TITLE_TAG = "*title*";
const string NEW_LINE = "\n";
public static readonly string[] Headers = new string[3]{
"playname=", // 当前播放的网址
"topindex=0", // 当前播放的序号
"saveplaypos=0"
};
/// <summary>
/// 转换文件
/// </summary>
/// <param name="dist"></param>
/// <param name="source"></param>
public static void Converter(string dist, string source)
{
using (var sourceStream = new FileStream(source, FileMode.Open))
{
using (var distStream = new FileStream(dist, FileMode.Create))
{
Converter(distStream, sourceStream);
}
}
}
/// <summary>
/// 转换文件
/// </summary>
/// <param name="dist"></param>
/// <param name="source"></param>
public static void Converter(FileStream dist, FileStream source)
{
Reset(source);
var encoder = new TxtEncoder();
var encoding = encoder.GetEncoding(source);
source.Seek(encoder.Position, SeekOrigin.Begin);
var line = ReadLine(source, encoding);
if (line.Trim() == HEADER_TAG)
{
Reset(source);
Copy(dist, source);
return;
}
source.Seek(encoder.Position, SeekOrigin.Begin);
Write(dist, HEADER_TAG);
Write(dist, NEW_LINE);
foreach (var item in Headers)
{
Write(dist, item);
Write(dist, NEW_LINE);
}
var i = 1;
while (null != (line = ReadLine(source, encoding)))
{
if (string.IsNullOrWhiteSpace(line))
{
continue;
}
var args = line.Split(',');
if (args.Length < 2)
{
continue;
}
Write(dist, i.ToString());
Write(dist, FILE_TAG);
Write(dist, args[1]);
Write(dist, NEW_LINE);
Write(dist, i.ToString());
Write(dist, TITLE_TAG);
Write(dist, args[0]);
Write(dist, NEW_LINE);
i++;
}
}
/// <summary>
/// 移动指针到开始位置
/// </summary>
/// <param name="source"></param>
private static void Reset(Stream source)
{
source.Seek(0, SeekOrigin.Begin);
}
/// <summary>
/// 复制流
/// </summary>
/// <param name="dist"></param>
/// <param name="source"></param>
private static void Copy(FileStream dist, FileStream source)
{
source.CopyTo(dist);
}
/// <summary>
/// 读取一行
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
private static string ReadLine(FileStream source, Encoding encoding)
{
var bytes = new List<byte>();
int code;
bool hasByte = false;
while ((code = source.ReadByte()) != -1)
{
hasByte = true;
if (code == 0x0a/* \n */ || code == 0x0d /* \r */)
{
break;
}
bytes.Add(Convert.ToByte(code));
}
if (!hasByte)
{
return null;
}
if (bytes.Count < 1)
{
return "";
}
return encoding.GetString(bytes.ToArray());
}
/// <summary>
/// 写入字符
/// </summary>
/// <param name="dist"></param>
/// <param name="line"></param>
private static void Write(FileStream dist, string line)
{
var bytes = Encoding.UTF8.GetBytes(line);
dist.Write(bytes, 0, bytes.Length);
}
获取编码
/// <summary>
/// 用于取得一个文本文件的编码方式(Encoding)。
/// </summary>
public class TxtEncoder
{
/// <summary>
/// 正文开始的位置
/// </summary>
public int Position { get; private set; } = 0;
/// <summary>
/// 取得一个文本文件的编码方式。如果无法在文件头部找到有效的前导符,Encoding.Default将被返回。
/// </summary>
/// <param name="fileName">文件名。</param>
/// <returns></returns>
public Encoding GetEncoding(string fileName)
{
return GetEncoding(fileName, Encoding.Default);
}
/// <summary>
/// 取得一个文本文件流的编码方式。
/// </summary>
/// <param name="stream">文本文件流。</param>
/// <returns></returns>
public Encoding GetEncoding(FileStream stream)
{
return GetEncoding(stream, Encoding.Default);
}
/// <summary>
/// 取得一个文本文件的编码方式。
/// </summary>
/// <param name="fileName">文件名。</param>
/// <param name="defaultEncoding">默认编码方式。当该方法无法从文件的头部取得有效的前导符时,将返回该编码方式。</param>
/// <returns></returns>
public Encoding GetEncoding(string fileName, Encoding defaultEncoding)
{
var fs = new FileStream(fileName, FileMode.Open);
var targetEncoding = GetEncoding(fs, defaultEncoding);
fs.Close();
return targetEncoding;
}
/// <summary>
/// 取得一个文本文件流的编码方式。
/// </summary>
/// <param name="stream">文本文件流。</param>
/// <param name="defaultEncoding">默认编码方式。当该方法无法从文件的头部取得有效的前导符时,将返回该编码方式。</param>
/// <returns></returns>
public Encoding GetEncoding(FileStream stream, Encoding defaultEncoding)
{
var targetEncoding = defaultEncoding;
if (stream == null || stream.Length < 2) return targetEncoding;
//保存文件流的前4个字节
byte byte3 = 0;
//保存当前Seek位置
var origPos = stream.Seek(0, SeekOrigin.Begin);
stream.Seek(0, SeekOrigin.Begin);
var nByte = stream.ReadByte();
var byte1 = Convert.ToByte(nByte);
var byte2 = Convert.ToByte(stream.ReadByte());
if (stream.Length >= 3)
{
byte3 = Convert.ToByte(stream.ReadByte());
}
//根据文件流的前4个字节判断Encoding
//Unicode {0xFF, 0xFE};
//BE-Unicode {0xFE, 0xFF};
//UTF8 = {0xEF, 0xBB, 0xBF};
if (byte1 == 0xFE && byte2 == 0xFF)//UnicodeBe
{
targetEncoding = Encoding.BigEndianUnicode;
Position = 2;
}
else if (byte1 == 0xFF && byte2 == 0xFE && byte3 != 0xFF)//Unicode
{
targetEncoding = Encoding.Unicode;
Position = 3;
}
else if (byte1 == 0xEF && byte2 == 0xBB && byte3 == 0xBF) //UTF8
{
targetEncoding = Encoding.UTF8;
Position = 3;
}
else
{
stream.Seek(0, SeekOrigin.Begin);
int read;
while ((read = stream.ReadByte()) != -1)
{
if (read >= 0xF0)
break;
if (0x80 <= read && read <= 0xBF)
break;
if (0xC0 <= read && read <= 0xDF)
{
read = stream.ReadByte();
if (0x80 <= read && read <= 0xBF)
continue;
break;
}
if (0xE0 > read || read > 0xEF) continue;
read = stream.ReadByte();
if (0x80 <= read && read <= 0xBF)
{
read = stream.ReadByte();
if (0x80 <= read && read <= 0xBF)
{
targetEncoding = Encoding.UTF8;
}
}
break;
}
}
//恢复Seek位置
stream.Seek(origPos, SeekOrigin.Begin);
return targetEncoding;
}
}
转载请保留原文链接: https://zodream.cn/blog/id/177.html