Skip to content

Commit c49e75b

Browse files
committed
F Added JPG sample
1 parent 61d93b8 commit c49e75b

1 file changed

Lines changed: 62 additions & 41 deletions

File tree

src/RTSPServerApp/RTSPServerWorker.cs

Lines changed: 62 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -50,69 +50,89 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
5050
ITrack rtspVideoTrack = null;
5151
ITrack rtspAudioTrack = null;
5252

53-
// frag_bunny.mp4 audio is not playable in VLC on Windows 11 (works on MacOS)
54-
using (Stream fs = new BufferedStream(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)))
53+
if (Path.GetExtension(fileName) == ".mp4")
5554
{
56-
using (var fmp4 = await FragmentedMp4.ParseAsync(fs))
55+
// frag_bunny.mp4 audio is not playable in VLC on Windows 11 (works on MacOS)
56+
using (Stream fs = new BufferedStream(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)))
5757
{
58-
videoTrackBox = fmp4.FindVideoTracks().FirstOrDefault();
59-
audioTrackBox = fmp4.FindAudioTracks().FirstOrDefault();
60-
61-
parsedMDAT = await fmp4.ParseMdatAsync();
62-
63-
if (videoTrackBox != null)
58+
using (var fmp4 = await FragmentedMp4.ParseAsync(fs))
6459
{
65-
videoTrackId = fmp4.FindVideoTrackID().First();
66-
videoFrameRate = fmp4.CalculateFrameRate(videoTrackBox);
60+
videoTrackBox = fmp4.FindVideoTracks().FirstOrDefault();
61+
audioTrackBox = fmp4.FindAudioTracks().FirstOrDefault();
6762

68-
var h264VisualSample = videoTrackBox.GetMdia().GetMinf().GetStbl().GetStsd().Children.FirstOrDefault(x => x.Type == VisualSampleEntryBox.TYPE3 || x.Type == VisualSampleEntryBox.TYPE4) as VisualSampleEntryBox;
69-
if (h264VisualSample != null)
70-
{
71-
var avcC = (h264VisualSample.Children.First(x => x.Type == AvcConfigurationBox.TYPE) as AvcConfigurationBox).AvcDecoderConfigurationRecord;
72-
rtspVideoTrack = new SharpRTSPServer.H264Track(avcC.AvcProfileIndication, 0, avcC.AvcLevelIndication);
73-
_server.AddVideoTrack(rtspVideoTrack);
74-
}
75-
else
63+
parsedMDAT = await fmp4.ParseMdatAsync();
64+
65+
if (videoTrackBox != null)
7666
{
77-
var h265VisualSample = videoTrackBox.GetMdia().GetMinf().GetStbl().GetStsd().Children.FirstOrDefault(x => x.Type == VisualSampleEntryBox.TYPE6 || x.Type == VisualSampleEntryBox.TYPE7) as VisualSampleEntryBox;
78-
if (h265VisualSample != null)
67+
videoTrackId = fmp4.FindVideoTrackID().First();
68+
videoFrameRate = fmp4.CalculateFrameRate(videoTrackBox);
69+
70+
var h264VisualSample = videoTrackBox.GetMdia().GetMinf().GetStbl().GetStsd().Children.FirstOrDefault(x => x.Type == VisualSampleEntryBox.TYPE3 || x.Type == VisualSampleEntryBox.TYPE4) as VisualSampleEntryBox;
71+
if (h264VisualSample != null)
7972
{
80-
rtspVideoTrack = new SharpRTSPServer.H265Track();
73+
var avcC = (h264VisualSample.Children.First(x => x.Type == AvcConfigurationBox.TYPE) as AvcConfigurationBox).AvcDecoderConfigurationRecord;
74+
rtspVideoTrack = new SharpRTSPServer.H264Track(avcC.AvcProfileIndication, 0, avcC.AvcLevelIndication);
8175
_server.AddVideoTrack(rtspVideoTrack);
8276
}
8377
else
8478
{
85-
throw new NotSupportedException("No supported video found!");
79+
var h265VisualSample = videoTrackBox.GetMdia().GetMinf().GetStbl().GetStsd().Children.FirstOrDefault(x => x.Type == VisualSampleEntryBox.TYPE6 || x.Type == VisualSampleEntryBox.TYPE7) as VisualSampleEntryBox;
80+
if (h265VisualSample != null)
81+
{
82+
rtspVideoTrack = new SharpRTSPServer.H265Track();
83+
_server.AddVideoTrack(rtspVideoTrack);
84+
}
85+
else
86+
{
87+
throw new NotSupportedException("No supported video found!");
88+
}
8689
}
8790
}
88-
}
89-
90-
if (audioTrackBox != null)
91-
{
92-
audioTrackId = fmp4.FindAudioTrackID().First();
9391

94-
var audioSampleEntry = audioTrackBox.GetAudioSampleEntryBox();
95-
if (audioSampleEntry.Type == AudioSampleEntryBox.TYPE3) // AAC
92+
if (audioTrackBox != null)
9693
{
97-
var audioConfigDescriptor = audioSampleEntry.GetAudioSpecificConfigDescriptor();
98-
int audioSamplingRate = audioConfigDescriptor.GetSamplingFrequency();
99-
rtspAudioTrack = new SharpRTSPServer.AACTrack(await audioConfigDescriptor.ToBytes(), audioSamplingRate, audioConfigDescriptor.ChannelConfiguration);
100-
_server.AddAudioTrack(rtspAudioTrack);
101-
}
102-
else
103-
{
104-
// unsupported audio
94+
audioTrackId = fmp4.FindAudioTrackID().First();
95+
96+
var audioSampleEntry = audioTrackBox.GetAudioSampleEntryBox();
97+
if (audioSampleEntry.Type == AudioSampleEntryBox.TYPE3) // AAC
98+
{
99+
var audioConfigDescriptor = audioSampleEntry.GetAudioSpecificConfigDescriptor();
100+
int audioSamplingRate = audioConfigDescriptor.GetSamplingFrequency();
101+
rtspAudioTrack = new SharpRTSPServer.AACTrack(await audioConfigDescriptor.ToBytes(), audioSamplingRate, audioConfigDescriptor.ChannelConfiguration);
102+
_server.AddAudioTrack(rtspAudioTrack);
103+
}
104+
else
105+
{
106+
// unsupported audio
107+
}
105108
}
106109
}
107110
}
108111
}
112+
else
113+
{
114+
parsedMDAT = new Dictionary<uint, IList<IList<byte[]>>>();
115+
parsedMDAT.Add(videoTrackId, new List<IList<byte[]>>());
116+
117+
var jpgFiles = Directory.GetFiles(fileName, "*.jpg");
118+
for (int i = 0; i < jpgFiles.Length; i++)
119+
{
120+
parsedMDAT[videoTrackId].Add(new List<byte[]>());
121+
parsedMDAT[videoTrackId][i].Add(File.ReadAllBytes(jpgFiles[i]));
122+
}
123+
124+
rtspVideoTrack = new SharpRTSPServer.MJpegTrack() { Width = 1160, Height = 768 };
125+
_server.AddVideoTrack(rtspVideoTrack);
126+
127+
videoFrameRate = 1;
128+
}
109129

110130
int videoIndex = 0;
111131
int audioIndex = 0;
112132
Timer audioTimer = null;
113133
Timer videoTimer = null;
114134

115-
if (videoTrackBox != null)
135+
if (rtspVideoTrack != null)
116136
{
117137
var videoSamplingRate = SharpRTSPServer.H264Track.DEFAULT_CLOCK;
118138
var videoSampleDuration = videoSamplingRate / videoFrameRate;
@@ -125,12 +145,13 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
125145
if (rtspVideoTrack is SharpRTSPServer.H264Track h264VideoTrack)
126146
{
127147
h264VideoTrack.SetParameterSets(videoTrack[0][0], videoTrack[0][1]);
148+
videoIndex++;
128149
}
129150
else if (rtspVideoTrack is SharpRTSPServer.H265Track h265VideoTrack)
130151
{
131152
h265VideoTrack.SetParameterSets(videoTrack[0][0], videoTrack[0][1], videoTrack[0][2]);
153+
videoIndex++;
132154
}
133-
videoIndex++;
134155
}
135156

136157
rtspVideoTrack.FeedInRawSamples((uint)(videoIndex * videoSampleDuration), (List<byte[]>)videoTrack[videoIndex++ % videoTrack.Count]);
@@ -142,7 +163,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
142163
};
143164
}
144165

145-
if (audioTrackBox != null)
166+
if (rtspAudioTrack != null)
146167
{
147168
var audioSampleDuration = SharpMp4.AACTrack.AAC_SAMPLE_SIZE;
148169
var audioTrack = parsedMDAT[audioTrackId];

0 commit comments

Comments
 (0)