@0biwank/screen-capture 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0biwank/screen-capture",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "Native screen + audio capture for macOS with file-backed HLS output.",
5
5
  "main": "index.js",
6
6
  "gypfile": false,
@@ -41,11 +41,6 @@
41
41
  "index.d.ts",
42
42
  "prebuilds/**/*.node",
43
43
  "prebuilds/SHA256SUMS",
44
- "binding.gyp",
45
- "include/**/*",
46
- "src/**/*",
47
- "scripts/**/*",
48
- "vendor/ffmpeg/README.md",
49
44
  "README.md",
50
45
  "SOURCE.md",
51
46
  "THIRD_PARTY_NOTICES.md",
@@ -1,2 +1,2 @@
1
- 92899877a4d6a464d7742998221b410ea2a404fe113743c8243c1ed3917e82b9 darwin-arm64/native_capture.node
2
- e6b6659d0e18c782a1cd95964fc7c263f771500ded12b4a1bcc996af448dac59 darwin-x64/native_capture.node
1
+ 58b47e3851865c139191fcbe940b2cad6247511b99094874971ba238e63c4aa3 darwin-arm64/native_capture.node
2
+ c5f205c3297f81269d74f2d6a6bd97bbd7f96a7c47c130b19c2f5395ccec2fb7 darwin-x64/native_capture.node
package/binding.gyp DELETED
@@ -1,58 +0,0 @@
1
- {
2
- "targets": [
3
- {
4
- "target_name": "native_capture",
5
- "sources": [
6
- "src/addon.cpp",
7
- "src/SourceHelper.mm",
8
- "src/SourceHelperWrapper.mm",
9
- "src/DesktopCapturer.mm",
10
- "src/CameraCapturer.mm",
11
- "src/MediaPipeline.cpp",
12
- "src/HLSMuxer/VideoEncoder.cpp",
13
- "src/HLSMuxer/AudioEncoder.cpp",
14
- "src/HLSMuxer/FileHLSMuxer.cpp"
15
- ],
16
- "include_dirs": [
17
- "<!@(node -p \"require('node-addon-api').include\")",
18
- "./vendor/ffmpeg/darwin-<(target_arch)/include",
19
- "./include"
20
- ],
21
- "libraries": [
22
- "<(module_root_dir)/vendor/ffmpeg/darwin-<(target_arch)/lib/libavformat.a",
23
- "<(module_root_dir)/vendor/ffmpeg/darwin-<(target_arch)/lib/libavcodec.a",
24
- "<(module_root_dir)/vendor/ffmpeg/darwin-<(target_arch)/lib/libswscale.a",
25
- "<(module_root_dir)/vendor/ffmpeg/darwin-<(target_arch)/lib/libswresample.a",
26
- "<(module_root_dir)/vendor/ffmpeg/darwin-<(target_arch)/lib/libavutil.a",
27
- "<(module_root_dir)/vendor/ffmpeg/darwin-<(target_arch)/lib/libx264.a",
28
- "-lm"
29
- ],
30
- "cflags!": ["-fno-exceptions", "-fno-rtti"],
31
- "cflags_cc!": ["-fno-exceptions", "-fno-rtti"],
32
- "defines": ["NAPI_DISABLE_CPP_EXCEPTIONS"],
33
- "conditions": [
34
- ["OS==\"mac\"", {
35
- "xcode_settings": {
36
- "CLANG_ENABLE_OBJC_ARC": "YES",
37
- "GCC_ENABLE_CPP_EXCEPTIONS": "YES",
38
- "GCC_ENABLE_CPP_RTTI": "YES",
39
- "MACOSX_DEPLOYMENT_TARGET": "14.0",
40
- "OTHER_LDFLAGS": [
41
- "-framework", "Foundation",
42
- "-framework", "AVFoundation",
43
- "-framework", "CoreAudio",
44
- "-framework", "AudioUnit",
45
- "-framework", "AudioToolbox",
46
- "-framework", "CoreMedia",
47
- "-framework", "CoreVideo",
48
- "-framework", "ApplicationServices",
49
- "-framework", "CoreGraphics",
50
- "-framework", "CoreFoundation",
51
- "-framework", "ScreenCaptureKit"
52
- ]
53
- }
54
- }]
55
- ]
56
- }
57
- ]
58
- }
@@ -1,54 +0,0 @@
1
- #pragma once
2
- #include <string>
3
- #include <vector>
4
- #include <functional>
5
-
6
- /**
7
- * CameraDevice
8
- * ------------
9
- * Represents a physical camera found by AVCaptureDevice.
10
- */
11
- struct CameraDevice {
12
- std::string uid;
13
- std::string name;
14
- };
15
-
16
- /**
17
- * CameraFrameCallback
18
- * -------------------
19
- * Returns a CMSampleBufferRef (as void*) containing the raw camera frame.
20
- */
21
- using CameraFrameCallback = std::function<void(void* cm_sample_buffer_ref)>;
22
-
23
- /**
24
- * CameraCapturer
25
- * --------------
26
- * A standalone macOS camera capturer using AVCaptureSession.
27
- * Isolated from ScreenCaptureKit to ensure a clean architecture.
28
- */
29
- class CameraCapturer {
30
- public:
31
- CameraCapturer();
32
- ~CameraCapturer();
33
-
34
- /** List all available video input devices (cameras) on this Mac. */
35
- static std::vector<CameraDevice> listDevices();
36
-
37
- /**
38
- * Start capturing from a specific camera.
39
- * @param device_uid The unique ID of the camera (empty for default).
40
- * @param width Requested width (closest match used).
41
- * @param height Requested height (closest match used).
42
- * @param fps Requested framerate.
43
- * @param cb Callback triggered for every raw frame.
44
- */
45
- bool start(const std::string& device_uid, uint32_t& width, uint32_t& height, int fps, CameraFrameCallback cb);
46
-
47
- /** Stop the capture session and release hardware resources. */
48
- void stop();
49
-
50
- private:
51
- // ObjC objects (void* to avoid ObjC headers in C++ includes)
52
- void* m_session = nullptr; // AVCaptureSession
53
- void* m_delegate = nullptr; // AVCaptureVideoDataOutputSampleBufferDelegate
54
- };
@@ -1,83 +0,0 @@
1
- #pragma once
2
-
3
- #include "Types.h"
4
- #include <atomic>
5
- #include <functional>
6
- #include <memory>
7
- #include <string>
8
-
9
- using SegmentReadyCallback = std::function<void(const std::string&)>;
10
-
11
- struct CaptureOptions
12
- {
13
- CGDirectDisplayID display_id = 0;
14
- bool capture_window = false;
15
- CGWindowID window_id = 0;
16
- bool no_screen = false;
17
-
18
- bool camera = false;
19
- std::string camera_device_uid;
20
-
21
- uint32_t width = 1920;
22
- uint32_t height = 1080;
23
- uint32_t fps = 30;
24
- uint32_t gop_size = 30;
25
- uint32_t video_bitrate = 9'000'000;
26
- bool crop_enabled = false;
27
- uint32_t crop_x = 0;
28
- uint32_t crop_y = 0;
29
- uint32_t crop_width = 0;
30
- uint32_t crop_height = 0;
31
-
32
- bool system_audio = true;
33
- bool microphone = false;
34
- std::string mic_device_uid;
35
- uint32_t sample_rate = 48000;
36
- uint32_t audio_bitrate = 128'000;
37
- uint32_t channels = 2;
38
- bool exclude_app_audio = false;
39
-
40
- std::string output_dir;
41
- std::string recording_id;
42
- uint32_t segment_time_sec = 4;
43
- };
44
-
45
- class DesktopCapturer
46
- {
47
- public:
48
- DesktopCapturer();
49
- ~DesktopCapturer();
50
-
51
- bool selectSource(CaptureSource source);
52
- bool startCapture(const CaptureOptions &options, SegmentReadyCallback segment_ready_callback = nullptr);
53
- bool stopCapture();
54
- bool pauseCapture();
55
- bool resumeCapture();
56
- const std::string &lastError() const { return m_last_error; }
57
-
58
- void on_video_sample(void *cm_sample_buffer_ref);
59
- void on_camera_sample(void *cm_sample_buffer_ref);
60
- void on_audio_sample(void *cm_sample_buffer_ref);
61
- void on_mic_pcm(const float *data, uint32_t frames, uint32_t sample_rate, uint32_t channels,
62
- double host_time_sec);
63
-
64
- private:
65
- void *m_stream = nullptr;
66
- void *m_config = nullptr;
67
- void *m_filter = nullptr;
68
- void *m_delegate = nullptr;
69
- void *m_audio_engine = nullptr;
70
- void *m_camera_capturer = nullptr;
71
-
72
- CaptureSource m_source;
73
- CaptureOptions m_options;
74
- std::string m_last_error;
75
-
76
- bool m_capturing = false;
77
-
78
- struct Impl;
79
- std::unique_ptr<Impl> m_impl;
80
-
81
- bool setup_mic_capture();
82
- void stop_mic_capture();
83
- };
@@ -1,75 +0,0 @@
1
- #pragma once
2
-
3
- #include <iostream>
4
- #include <queue>
5
- #include <string>
6
- #include "Types.h"
7
- #include <vector>
8
- #include <cstdint>
9
-
10
- extern "C"
11
- {
12
- struct AVCodec;
13
- struct AVStream;
14
- struct AVFormatContext;
15
- struct AVCodecContext;
16
- struct SwrContext;
17
- struct AVAudioFifo;
18
- struct AVFrame;
19
- struct AVPacket;
20
- }
21
-
22
- class AudioEncoder
23
- {
24
- private:
25
- // state variables
26
- bool m_initialized;
27
-
28
- // conversion essentials
29
- int m_sampleRate;
30
- int m_channels;
31
- int m_bitrate;
32
- int64_t m_pts;
33
- int64_t m_sampleCount;
34
- int64_t m_nextInputPts;
35
- std::queue<AVPacket *> m_packetQueue;
36
- std::vector<std::string> m_chunkFileNames;
37
-
38
- // FFMpeg
39
- const AVCodec *m_codec;
40
- OutputMode mode;
41
- AVCodecContext *m_codecContext;
42
- SwrContext *m_swrContext;
43
- AVAudioFifo *m_audioFifo;
44
- AVFrame *m_frame;
45
-
46
- // standalone
47
- AVStream *m_stream;
48
- AVFormatContext *m_formatContext;
49
- int currentChunkIndex;
50
- double targetChunkDuration;
51
- int64_t currentSegmentStartPts;
52
- double currentSegmentDuration;
53
-
54
- private:
55
- bool shouldStartNewChunk() const;
56
- void forceNewChunk();
57
- // Drain encoder and handle remaining packets based on mode
58
- void flushEncoder();
59
-
60
- public:
61
- AudioEncoder();
62
- ~AudioEncoder();
63
- bool initialize(int sampleRate, int channels, int bitrate, OutputMode mode);
64
- bool encodeSamples(const uint8_t *samples, int numSamples, int64_t pts = -1);
65
- AVPacket *getNextPacket();
66
- bool hasPackets() const;
67
- std::string generatePlaylist() const;
68
- void cleanup();
69
-
70
- bool isInitialized() { return m_initialized; }
71
- int getSampleRate() { return m_sampleRate; }
72
- int getChannels() { return m_channels; }
73
- const AVCodecContext *getCodecContext() const { return m_codecContext; }
74
- OutputMode getMode() const { return mode; }
75
- };
@@ -1,63 +0,0 @@
1
- #pragma once
2
-
3
- #include <cstdint>
4
- #include <functional>
5
- #include <set>
6
- #include <string>
7
-
8
- extern "C" {
9
- struct AVBSFContext;
10
- struct AVCodecContext;
11
- struct AVFormatContext;
12
- struct AVPacket;
13
- struct AVStream;
14
- }
15
-
16
- class FileHLSMuxer {
17
- public:
18
- FileHLSMuxer();
19
- ~FileHLSMuxer();
20
-
21
- bool init(const std::string& output_dir,
22
- const std::string& recording_id,
23
- int segment_time_sec,
24
- const AVCodecContext* video_codec_ctx,
25
- const AVCodecContext* audio_codec_ctx);
26
-
27
- void set_expected_segment_duration_ms(double duration_ms);
28
- void set_segment_ready_callback(std::function<void(const std::string&)> callback);
29
-
30
- void push_video(AVPacket* pkt);
31
- void push_audio(AVPacket* pkt);
32
-
33
- void shutdown();
34
- bool is_initialized() const { return m_initialized; }
35
-
36
- private:
37
- int write_packet(AVPacket* pkt, bool is_video);
38
- bool init_h264_bsf_if_needed();
39
- void log_overlong_segment_if_needed(AVPacket* pkt);
40
- void notify_ready_segments();
41
-
42
- AVFormatContext* m_fmt_ctx = nullptr;
43
- AVStream* m_video_stream = nullptr;
44
- AVStream* m_audio_stream = nullptr;
45
- AVBSFContext* m_h264_bsf_ctx = nullptr;
46
-
47
- std::string m_output_dir;
48
- std::string m_recording_id;
49
- std::string m_playlist_path;
50
- std::set<std::string> m_notified_segments;
51
- std::function<void(const std::string&)> m_segment_ready_callback;
52
- bool m_initialized = false;
53
-
54
- int m_fps = 30;
55
- int m_sample_rate = 48000;
56
- int m_audio_frame_samples = 1024;
57
- int m_video_tb_num = 1;
58
- int m_video_tb_den = 30;
59
- int m_audio_tb_num = 1;
60
- int m_audio_tb_den = 48000;
61
- double m_expected_segment_duration_ms = 0.0;
62
- int64_t m_last_segment_key_pts = -1;
63
- };
@@ -1,13 +0,0 @@
1
- #include <Foundation/Foundation.h>
2
-
3
- extern "C" {
4
- #include <libavcodec/avcodec.h>
5
- #include <libavformat/avformat.h>
6
- #include <libswresample/swresample.h>
7
- }
8
-
9
- class Encoder {
10
- private:
11
- bool m_Initialized;
12
-
13
- };
@@ -1,90 +0,0 @@
1
- #pragma once
2
- /*
3
- This Encoder in the default format needs to produce H264 packets
4
- and when in the seperate stream mode it needs to produces TS chunks.
5
-
6
- - Input: CVPixelBufferRef, BGRA
7
- - Output:
8
- - Default: H264 packets for the TS Muxer to process
9
- - Seperate Stream: TS chunks with playlist.
10
-
11
- I need to track frame count, timestamps, keyframes
12
- */
13
-
14
- #include "Types.h"
15
- #include <cstdint>
16
- #include <iostream>
17
- #include <queue>
18
- #include <vector>
19
-
20
- extern "C"
21
- {
22
- struct AVCodecContext;
23
- struct AVPacket;
24
- struct AVCodec;
25
- struct AVFrame;
26
- struct SwsContext;
27
- struct AVStream;
28
- struct AVFormatContext;
29
- }
30
-
31
- class VideoEncoder
32
- {
33
- // all variables
34
- private:
35
- int frameHeight;
36
- int frameWidth;
37
- int frameRate;
38
- bool isPaused;
39
- bool m_initialized;
40
-
41
- // FFMPEG
42
- AVCodecContext *m_codecContext;
43
- const AVCodec *m_codec;
44
- AVStream *m_stream;
45
- AVFormatContext *m_formatContext;
46
- AVFrame *m_frame;
47
- SwsContext *m_swsContext;
48
-
49
- // Timing & state
50
- int64_t m_frameCount;
51
- int64_t m_pts;
52
- int64_t m_dts;
53
- int64_t m_lastInputPts;
54
- int64_t currentSegmentStartPts;
55
- double currentSegmentDuration;
56
-
57
- // Chunking
58
- int currentChunkIndex;
59
- double targetChunkDuration;
60
- OutputMode mode;
61
- std::vector<std::string> m_chunkFileNames;
62
-
63
- // output buffer
64
- std::queue<AVPacket *> m_packetQueue;
65
-
66
- // all functions
67
- public:
68
- VideoEncoder();
69
- ~VideoEncoder();
70
- bool initialize(int width, int height, int fps, int bitrate, OutputMode mode, int gopSize = 0);
71
- bool encodeFrame(uint8_t *pixelData, int stride, int64_t pts = -1);
72
- void cleanup();
73
-
74
- // Chunk control
75
- void forceKeyFrame();
76
- bool shouldStartNewChunk() const;
77
-
78
- // Muxed mode when we want just single stream
79
- AVPacket *getNextPacket();
80
- bool hasPackets() const;
81
- std::string generatePlaylist() const;
82
-
83
- // getters to get the state of the VideoEncoder
84
- bool isInitialized() const { return m_initialized; }
85
- int getWidth() const { return frameWidth; }
86
- int getHeigth() const { return frameHeight; }
87
- int getFPS() const { return frameRate; }
88
- int64_t getFrameCount() const { return m_frameCount; }
89
- const AVCodecContext *getCodecContext() const { return m_codecContext; }
90
- };
@@ -1,39 +0,0 @@
1
- #pragma once
2
- #include <cstdint>
3
- #include <functional>
4
- #include <memory>
5
- #include <string>
6
-
7
- struct PipelineConfig {
8
- int width = 1920;
9
- int height = 1080;
10
- int fps = 30;
11
- int gop_size = 30;
12
- int video_bitrate = 9'000'000;
13
- int sample_rate = 48000;
14
- int channels = 2;
15
- int audio_bitrate = 128'000;
16
- std::string output_dir;
17
- std::string recording_id;
18
- int segment_time_sec = 4;
19
- std::function<void(const std::string&)> segment_ready_callback;
20
- };
21
-
22
- class MediaPipeline {
23
- public:
24
- MediaPipeline();
25
- ~MediaPipeline();
26
-
27
- bool init(const PipelineConfig& cfg);
28
-
29
- void push_video_frame(const uint8_t* data, int stride, int64_t pts_ticks,
30
- bool is_keyframe_hint = false);
31
-
32
- void push_audio_s16(const int16_t* data, int num_frames, int64_t pts_samples);
33
-
34
- void flush_and_shutdown();
35
-
36
- private:
37
- struct Impl;
38
- std::unique_ptr<Impl> m_impl;
39
- };
@@ -1,41 +0,0 @@
1
- #pragma once
2
-
3
- #include <Foundation/Foundation.h>
4
- #include <ScreenCaptureKit/ScreenCaptureKit.h>
5
- #include <cstdint>
6
- #include <iostream>
7
- #include <vector>
8
- #include <ApplicationServices/ApplicationServices.h>
9
- /*
10
- food for thought: should I keep a shared
11
- list of sources that get refreshed every
12
- time, or should I just provide the functions
13
- to get the list?
14
-
15
- Both should be easy to do but ig we should
16
- go with the idea where I just return the list
17
- right!? Shouldn't complicate it too much
18
- */
19
-
20
- namespace SourceHelper
21
- {
22
- struct Displays
23
- {
24
- CGDirectDisplayID id;
25
- uint32_t width;
26
- uint32_t height;
27
- std::string title;
28
- bool isMain;
29
- };
30
- struct Windows
31
- {
32
- CGWindowID id;
33
- uint32_t width;
34
- uint32_t height;
35
- std::string title;
36
- // CGWindow
37
- };
38
- std::vector<Displays> getDisplaySources();
39
- std::vector<Windows> getWindowSources();
40
- bool isCaptureableWindow(const NSDictionary* windowInfo);
41
- }
@@ -1,29 +0,0 @@
1
- #pragma once
2
-
3
- #include <vector>
4
- #include <cstdint>
5
- #include <string>
6
-
7
- namespace SourceHelperWrapper
8
- {
9
- struct Display
10
- {
11
- uint32_t id;
12
- uint32_t width;
13
- uint32_t height;
14
- std::string title;
15
- bool isMain;
16
- };
17
-
18
- struct Window
19
- {
20
- uint32_t id;
21
- uint32_t width;
22
- uint32_t height;
23
- std::string title;
24
- };
25
-
26
- std::vector<Display> getDisplaySources();
27
- std::vector<Window> getWindowSources();
28
- bool isCaptureableWindow(uint32_t windowID);
29
- }
package/include/Types.h DELETED
@@ -1,58 +0,0 @@
1
- #pragma once
2
-
3
- // only use for universal type definitions
4
- #include <ApplicationServices/ApplicationServices.h>
5
- #include <CoreFoundation/CFCGTypes.h>
6
- #include <CoreGraphics/CGDirectDisplay.h>
7
- #include <CoreGraphics/CGGeometry.h>
8
- #include <CoreGraphics/CGWindow.h>
9
- #include <cstdint>
10
- #include <string>
11
-
12
- /*
13
- I think I wrote this very good ;)
14
- PS Claude helped too! Constructor was it's idea
15
-
16
-
17
- EDIT: modified to store the scContent
18
- */
19
- struct CaptureSource {
20
- bool isWindow;
21
- union {
22
- CGWindowID windowID;
23
- CGDirectDisplayID displayID;
24
- };
25
- void *scContent;
26
- uint32_t width;
27
- uint32_t height;
28
- std::string title;
29
- CGRect captureRect;
30
-
31
- static CaptureSource createWindow(CGWindowID id, uint32_t w, uint32_t h,
32
- std::string t) {
33
- CaptureSource s;
34
- s.isWindow = true;
35
- s.windowID = id;
36
- s.width = w;
37
- s.height = h;
38
- s.title = t;
39
- s.captureRect = CGRectMake(0, 0, w, h);
40
- s.scContent = nullptr;
41
- return s;
42
- }
43
-
44
- static CaptureSource createDisplay(CGDirectDisplayID id, uint32_t w,
45
- uint32_t h, std::string t) {
46
- CaptureSource s;
47
- s.isWindow = false;
48
- s.displayID = id;
49
- s.width = w;
50
- s.height = h;
51
- s.title = t;
52
- s.captureRect = CGRectMake(0, 0, w, h);
53
- s.scContent = nullptr;
54
- return s;
55
- }
56
- };
57
-
58
- enum class OutputMode { STANDALONE, MUXED };
@@ -1,9 +0,0 @@
1
- #include <cstdint>
2
- #include <iostream>
3
- #include <queue>
4
- #include <boost/asio.hpp>
5
-
6
- class UploadManager {
7
- private:
8
- std::queue<uint8_t> uploadQueue;
9
- };