1+ /*
2+ * Copyright 2025 Alex Andres
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+ package dev .onvoid .webrtc .examples .util ;
18+
19+ import dev .onvoid .webrtc .media .audio .AudioTrackSink ;
20+ import dev .onvoid .webrtc .media .video .VideoFrame ;
21+ import dev .onvoid .webrtc .media .video .VideoTrackSink ;
22+
23+ import org .slf4j .Logger ;
24+ import org .slf4j .LoggerFactory ;
25+
26+ /**
27+ * Utility class for logging audio and video frame information.
28+ *
29+ * @author Alex Andres
30+ */
31+ public class MediaFrameLogger {
32+
33+ private static final Logger LOG = LoggerFactory .getLogger (MediaFrameLogger .class );
34+
35+
36+ /**
37+ * Creates a new audio track sink that logs information about received audio data.
38+ *
39+ * @return An AudioTrackSink that logs audio frame information.
40+ */
41+ public static AudioTrackSink createAudioLogger () {
42+ return new AudioFrameLogger ();
43+ }
44+
45+ /**
46+ * Creates a new video track sink that logs information about received video frames.
47+ *
48+ * @return A VideoTrackSink that logs video frame information.
49+ */
50+ public static VideoTrackSink createVideoLogger () {
51+ return new VideoFrameLogger ();
52+ }
53+
54+
55+
56+ /**
57+ * A simple implementation of AudioTrackSink that logs information about received audio data.
58+ */
59+ private static class AudioFrameLogger implements AudioTrackSink {
60+
61+ private static final long LOG_INTERVAL_MS = 1000 ; // Log every second
62+ private int frameCount = 0 ;
63+ private long lastLogTime = System .currentTimeMillis ();
64+
65+ @ Override
66+ public void onData (byte [] data , int bitsPerSample , int sampleRate , int channels , int frames ) {
67+ frameCount ++;
68+
69+ long now = System .currentTimeMillis ();
70+ if (now - lastLogTime >= LOG_INTERVAL_MS ) {
71+ LOG .info (String .format ("Received %d audio frames in the last %.1f seconds" ,
72+ frameCount , (now - lastLogTime ) / 1000.0 ));
73+ LOG .info (String .format ("Last audio data: %d bytes, %d bits/sample, %d Hz, %d channels, %d frames" ,
74+ data .length , bitsPerSample , sampleRate , channels , frames ));
75+
76+ frameCount = 0 ;
77+ lastLogTime = now ;
78+ }
79+ }
80+ }
81+
82+
83+
84+ /**
85+ * A simple implementation of VideoTrackSink that logs information about received frames.
86+ */
87+ private static class VideoFrameLogger implements VideoTrackSink {
88+
89+ private static final long LOG_INTERVAL_MS = 1000 ; // Log every second
90+ private int frameCount = 0 ;
91+ private long lastLogTime = System .currentTimeMillis ();
92+
93+ @ Override
94+ public void onVideoFrame (VideoFrame frame ) {
95+ frameCount ++;
96+
97+ long now = System .currentTimeMillis ();
98+ if (now - lastLogTime >= LOG_INTERVAL_MS ) {
99+ LOG .info (String .format ("Received %d video frames in the last %.1f seconds" ,
100+ frameCount , (now - lastLogTime ) / 1000.0 ));
101+ LOG .info (String .format ("Last frame: %dx%d, rotation: %d, timestamp: %dms" ,
102+ frame .buffer .getWidth (), frame .buffer .getHeight (), frame .rotation ,
103+ frame .timestampNs / 1000000 ));
104+
105+ frameCount = 0 ;
106+ lastLogTime = now ;
107+ }
108+
109+ // Release the native resources associated with this frame to prevent memory leaks.
110+ frame .release ();
111+ }
112+ }
113+ }
0 commit comments