-
-
Notifications
You must be signed in to change notification settings - Fork 492
/
Copy pathRemoteFileStream.cs
124 lines (107 loc) · 3.59 KB
/
RemoteFileStream.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//
// Copyright Fela Ameghino 2015-2025
//
// Distributed under the GNU General Public License v3.0. (See accompanying
// file LICENSE or copy at https://www.gnu.org/licenses/gpl-3.0.txt)
//
using LibVLCSharp.Shared;
using System;
using Telegram.Native;
using Telegram.Services;
using Telegram.Td.Api;
namespace Telegram.Streams
{
public partial class RemoteFileStream : MediaInput
{
private readonly File _file;
private readonly RemoteFileSource _source;
private FileStreamFromApp _fileStream;
private string _filePath;
private bool _disposed;
public RemoteFileStream(IClientService clientService, File file)
{
_file = file;
_source = new RemoteFileSource(clientService, file);
CanSeek = true;
}
/// <summary>
/// LibVLC calls this method when it wants to open the media
/// </summary>
/// <param name="size">This value must be filled with the length of the media (or ulong.MaxValue if unknown)</param>
/// <returns><c>true</c> if the stream opened successfully</returns>
public override bool Open(out ulong size)
{
size = (ulong)_file.Size;
_source.Open();
return true;
}
/// <summary>
/// LibVLC calls this method when it wants to read the media
/// </summary>
/// <param name="buf">The buffer where read data must be written</param>
/// <param name="len">The buffer length</param>
/// <returns>strictly positive number of bytes read, 0 on end-of-stream, or -1 on non-recoverable error</returns>
public unsafe override int Read(IntPtr buf, uint len)
{
try
{
_source.ReadCallback((int)len);
if (_disposed || _source.Offset == _file.Size)
{
return 0;
}
var path = _file.Local.Path;
if (path.Length > 0 && !_source.IsCanceled && (_fileStream == null || _filePath != path))
{
_fileStream?.Close();
_fileStream = new FileStreamFromApp(path);
_filePath = path;
}
else if (_fileStream == null)
{
return 0;
}
_fileStream.Seek(_source.Offset);
_source.SeekCallback(_source.Offset + len);
return _fileStream.Read((long)buf, len);
}
catch
{
return -1;
}
}
/// <summary>
/// LibVLC calls this method when it wants to seek to a specific position in the media
/// </summary>
/// <param name="offset">The offset, in bytes, since the beginning of the stream</param>
/// <returns><c>true</c> if the seek succeeded, false otherwise</returns>
public override bool Seek(ulong offset)
{
try
{
_source.SeekCallback((int)offset);
return true;
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// LibVLC calls this method when it wants to close the media.
/// </summary>
public override void Close()
{
try
{
_fileStream?.Close();
_fileStream = null;
_source.Close();
}
catch (Exception)
{
// ignored
}
}
}
}