@0biwank/screen-capture 1.0.1 → 2.0.1
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.
Potentially problematic release.
This version of @0biwank/screen-capture might be problematic. Click here for more details.
- package/LICENSE +339 -21
- package/LICENSES/CPP-HTTPLIB-MIT.txt +21 -0
- package/LICENSES/FFMPEG-GPLv2.txt +340 -0
- package/LICENSES/PROJECT-MIT.txt +21 -0
- package/LICENSES/X264-COPYING.txt +341 -0
- package/README.md +53 -64
- package/SOURCE.md +35 -0
- package/THIRD_PARTY_NOTICES.md +28 -0
- package/binding.gyp +58 -0
- package/include/CameraCapturer.h +54 -0
- package/include/DesktopCapturer.h +83 -0
- package/include/HLSMuxer/AudioEncoder.h +75 -0
- package/include/HLSMuxer/FileHLSMuxer.h +63 -0
- package/include/HLSMuxer/HLSMuxer.h +13 -0
- package/include/HLSMuxer/VideoEncoder.h +90 -0
- package/include/MediaPipeline.h +39 -0
- package/include/SourceHelper.h +41 -0
- package/include/SourceHelperWrapper.h +29 -0
- package/include/Types.h +58 -0
- package/include/UploadManager.h +9 -0
- package/include/httplib.h +12065 -0
- package/index.d.ts +99 -0
- package/index.js +105 -14
- package/package.json +31 -17
- package/prebuilds/SHA256SUMS +2 -0
- package/prebuilds/darwin-arm64/native_capture.node +0 -0
- package/prebuilds/darwin-x64/native_capture.node +0 -0
- package/scripts/build-ffmpeg-vendor.mjs +178 -0
- package/scripts/build.mjs +53 -0
- package/scripts/stage-prebuild.mjs +28 -0
- package/scripts/verify-package.mjs +39 -0
- package/scripts/verify-packlist.mjs +40 -0
- package/scripts/verify-runtime.cjs +28 -0
- package/src/CameraCapturer.mm +154 -0
- package/src/DesktopCapturer.mm +995 -0
- package/src/HLSMuxer/AudioEncoder.cpp +484 -0
- package/src/HLSMuxer/FileHLSMuxer.cpp +345 -0
- package/src/HLSMuxer/HLSMuxer.cpp +0 -0
- package/src/HLSMuxer/VideoEncoder.cpp +462 -0
- package/src/MediaPipeline.cpp +375 -0
- package/src/MediaProcessor.cpp +0 -0
- package/src/SourceHelper.mm +184 -0
- package/src/SourceHelperWrapper.mm +63 -0
- package/src/UploadManager.h +7 -0
- package/src/addon.cpp +347 -0
- package/vendor/ffmpeg/README.md +40 -0
- package/build/Release/media_processor.node +0 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
#import <AVFoundation/AVFoundation.h>
|
|
2
|
+
#import <CoreMedia/CoreMedia.h>
|
|
3
|
+
#include "CameraCapturer.h"
|
|
4
|
+
#include <iostream>
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* CameraDelegate
|
|
8
|
+
* --------------
|
|
9
|
+
* Internal ObjC class to receive frames from AVCaptureVideoDataOutput.
|
|
10
|
+
*/
|
|
11
|
+
@interface CameraDelegate : NSObject <AVCaptureVideoDataOutputSampleBufferDelegate> {
|
|
12
|
+
CameraFrameCallback _callback;
|
|
13
|
+
}
|
|
14
|
+
- (void)setCallback:(CameraFrameCallback)cb;
|
|
15
|
+
@end
|
|
16
|
+
|
|
17
|
+
@implementation CameraDelegate
|
|
18
|
+
- (void)setCallback:(CameraFrameCallback)cb {
|
|
19
|
+
_callback = cb;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
- (void)captureOutput:(AVCaptureOutput *)output
|
|
23
|
+
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
|
|
24
|
+
fromConnection:(AVCaptureConnection *)connection {
|
|
25
|
+
if (_callback) {
|
|
26
|
+
_callback(static_cast<void*>(sampleBuffer));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
@end
|
|
30
|
+
|
|
31
|
+
CameraCapturer::CameraCapturer() : m_session(nullptr), m_delegate(nullptr) {}
|
|
32
|
+
|
|
33
|
+
CameraCapturer::~CameraCapturer() {
|
|
34
|
+
stop();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
std::vector<CameraDevice> CameraCapturer::listDevices() {
|
|
38
|
+
std::vector<CameraDevice> result;
|
|
39
|
+
|
|
40
|
+
// Modern API for listing video devices
|
|
41
|
+
AVCaptureDeviceDiscoverySession *discoverySession = [AVCaptureDeviceDiscoverySession
|
|
42
|
+
discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera, AVCaptureDeviceTypeExternal]
|
|
43
|
+
mediaType:AVMediaTypeVideo
|
|
44
|
+
position:AVCaptureDevicePositionUnspecified];
|
|
45
|
+
|
|
46
|
+
for (AVCaptureDevice *device in discoverySession.devices) {
|
|
47
|
+
CameraDevice d;
|
|
48
|
+
d.uid = [[device uniqueID] UTF8String];
|
|
49
|
+
d.name = [[device localizedName] UTF8String];
|
|
50
|
+
result.push_back(d);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
bool CameraCapturer::start(const std::string& device_uid, uint32_t& width, uint32_t& height, int fps, CameraFrameCallback cb) {
|
|
57
|
+
stop(); // Ensure clean state
|
|
58
|
+
|
|
59
|
+
AVCaptureSession *session = [[AVCaptureSession alloc] init];
|
|
60
|
+
AVCaptureDevice *device = nil;
|
|
61
|
+
|
|
62
|
+
if (device_uid.empty()) {
|
|
63
|
+
device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
|
|
64
|
+
} else {
|
|
65
|
+
device = [AVCaptureDevice deviceWithUniqueID:[NSString stringWithUTF8String:device_uid.c_str()]];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (!device) {
|
|
69
|
+
std::cerr << "[Camera] Requested device not found: " << device_uid << std::endl;
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
NSError *error = nil;
|
|
74
|
+
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
|
|
75
|
+
if (error || !input) {
|
|
76
|
+
std::cerr << "[Camera] Failed to create input: " << [[error localizedDescription] UTF8String] << std::endl;
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if ([session canAddInput:input]) {
|
|
81
|
+
[session addInput:input];
|
|
82
|
+
} else {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
|
|
87
|
+
|
|
88
|
+
// Use 32BGRA for easy conversion / preview
|
|
89
|
+
[output setVideoSettings:@{
|
|
90
|
+
(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)
|
|
91
|
+
}];
|
|
92
|
+
|
|
93
|
+
CameraDelegate *delegate = [[CameraDelegate alloc] init];
|
|
94
|
+
[delegate setCallback:cb];
|
|
95
|
+
|
|
96
|
+
dispatch_queue_t queue = dispatch_queue_create("com.boom.camera.queue", DISPATCH_QUEUE_SERIAL);
|
|
97
|
+
[output setSampleBufferDelegate:delegate queue:queue];
|
|
98
|
+
|
|
99
|
+
if ([session canAddOutput:output]) {
|
|
100
|
+
[session addOutput:output];
|
|
101
|
+
} else {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Find best match for requested dimensions
|
|
106
|
+
AVCaptureDeviceFormat *bestFormat = nil;
|
|
107
|
+
int bestDiff = 9999999;
|
|
108
|
+
|
|
109
|
+
for (AVCaptureDeviceFormat *vFormat in [device formats]) {
|
|
110
|
+
CMFormatDescriptionRef description = [vFormat formatDescription];
|
|
111
|
+
CMVideoDimensions dims = CMVideoFormatDescriptionGetDimensions(description);
|
|
112
|
+
|
|
113
|
+
int diff = std::abs((int)dims.width - (int)width) + std::abs((int)dims.height - (int)height);
|
|
114
|
+
if (diff < bestDiff) {
|
|
115
|
+
bestDiff = diff;
|
|
116
|
+
bestFormat = vFormat;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (bestFormat) {
|
|
121
|
+
if ([device lockForConfiguration:nil]) {
|
|
122
|
+
device.activeFormat = bestFormat;
|
|
123
|
+
device.activeVideoMinFrameDuration = CMTimeMake(1, fps);
|
|
124
|
+
device.activeVideoMaxFrameDuration = CMTimeMake(1, fps);
|
|
125
|
+
[device unlockForConfiguration];
|
|
126
|
+
|
|
127
|
+
CMFormatDescriptionRef description = [bestFormat formatDescription];
|
|
128
|
+
CMVideoDimensions dims = CMVideoFormatDescriptionGetDimensions(description);
|
|
129
|
+
width = dims.width;
|
|
130
|
+
height = dims.height;
|
|
131
|
+
std::cout << "[Camera] Selected format: " << width << "x" << height << " @ " << fps << "fps" << std::endl;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
[session startRunning];
|
|
136
|
+
|
|
137
|
+
m_session = (__bridge_retained void*)session;
|
|
138
|
+
m_delegate = (__bridge_retained void*)delegate;
|
|
139
|
+
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
void CameraCapturer::stop() {
|
|
144
|
+
if (m_session) {
|
|
145
|
+
AVCaptureSession *session = (__bridge_transfer AVCaptureSession*)m_session;
|
|
146
|
+
[session stopRunning];
|
|
147
|
+
m_session = nullptr;
|
|
148
|
+
}
|
|
149
|
+
if (m_delegate) {
|
|
150
|
+
CameraDelegate *delegate = (__bridge_transfer CameraDelegate*)m_delegate;
|
|
151
|
+
[delegate setCallback:nullptr];
|
|
152
|
+
m_delegate = nullptr;
|
|
153
|
+
}
|
|
154
|
+
}
|