Skip to content

Commit

Permalink
Ctrl+z pause/resumes, prep README/CHANGELOG
Browse files Browse the repository at this point in the history
  • Loading branch information
matthutchinson committed Oct 26, 2021
1 parent f346820 commit a8db19f
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 28 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ adheres to [Semantic Versioning](Semver).

- Your contribution here!

## [0.0.8] - 2020-Oct-27
### Added
- Ctrl+z to pause/resume capture

### Changed
- Default filename postfixed with timestamp

## [0.0.7] - 2020-Oct-19
### Added
- Fix issues with connected iOS device discovery and build/test on M1 arch
Expand Down Expand Up @@ -58,7 +65,8 @@ adheres to [Semantic Versioning](Semver).
### Changed
- Initial release (using the QTKit framework)

[Unreleased]: https://github.com/matthutchinson/videosnap/compare/v0.0.7...HEAD
[Unreleased]: https://github.com/matthutchinson/videosnap/compare/v0.0.8...HEAD
[0.0.8]: https://github.com/matthutchinson/videosnap/compare/v0.0.7...v0.0.8
[0.0.7]: https://github.com/matthutchinson/videosnap/compare/v0.0.5...v0.0.7
[0.0.5]: https://github.com/matthutchinson/videosnap/compare/v0.0.4...v0.0.5
[0.0.4]: https://github.com/matthutchinson/videosnap/compare/v0.0.3...v0.0.4
Expand Down
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
# VideoSnap

VideoSnap is an macOS command line tool for recording video and audio from any
attached capture device (including any attached iOS device).
attached capture device (including screen capture from connected iOS devices).

You can specify which device to capture from, the duration, encoding and a delay
period (before capturing starts). You can also disable audio recording.
You can specify which device to capture from (by device name), the duration,
encoding and a delay period (before capturing starts).

By default VideoSnap will capture both video and audio from the default capture
device at 30fps, with a Medium quality preset and a short (0.5s) warm-up delay.

If no duration is specified, VideoSnap will record until you cancel with
[Ctrl+c]. You can also use VideoSnap to list attached capture devices by name.
[Ctrl+c] or you can pause (and resume) recording with [Ctrl+z].

VideoSnap can list attached capture devices by name.

## Requirements

* macOS 10.9+ (Intel/M1)
* A web cam
* A web cam or iOS device

If you need to capture video on older versions of macOS (e.g. 32-bit) try
If you need to capture video on older versions of macOS (e.g. 32-bit OSX) try
[wacaw](http://webcam-tools.sourceforge.net)

## Installation
Expand Down Expand Up @@ -84,9 +86,9 @@ Use the `-p` flag to choose a preset.

### Capturing from connected iOS devices

It is possible to screen capture video & audio from an attached iOS device.
It is possible to screen capture video & audio from an attached iOS device.

For the device to be discovered you must confirm that you
For the device to be discovered you must confirm that you
**Trust This Computer** on the device when it is connected and unlocked.

There are some limitations and issues with iOS screen capturing.
Expand Down Expand Up @@ -166,7 +168,6 @@ If you'd like to get involved in contributing, here are some ideas:

* Allow VideoSnap to pipe captured bytes to the STDOUT stream
* Submit VideoSnap as a package for [Homebrew](http://brew.sh)
* Default filename should include a timestamp of when recording began
* Allow more size/quality options for video and/or audio
* Smile detection while capturing video/image, determine a happiness factor/score
* Allow VideoSnap to capture a single frame to an image file (with compression
Expand Down
2 changes: 1 addition & 1 deletion videosnap/Constants.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

NSString *const VERSION = @"0.0.8";

int const DEFAULT_FRAMES_PER_SECOND = 30;
int const DEFAULT_FRAMES_PER_SECOND = 30;
float const DEFAULT_RECORDING_DELAY = 0.5;
NSString *const DEFAULT_ENCODING_PRESET = @"Medium";

Expand Down
20 changes: 13 additions & 7 deletions videosnap/VideoSnap.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@

// logging
#define error(...) fprintf(stderr, __VA_ARGS__)
#define console(...) printf(__VA_ARGS__)
#define verbose(...) (self->isVerbose && fprintf(stderr, __VA_ARGS__))
#define console(...) fprintf(stdout, __VA_ARGS__)
#define verbose(...) (self->isVerbose && fprintf(stdout, __VA_ARGS__))
#define verbose_error(...) (self->isVerbose && fprintf(stderr, __VA_ARGS__))

// VideoSnap
@interface VideoSnap : NSObject <AVCaptureFileOutputRecordingDelegate> {
AVCaptureSession *session;
AVCaptureSession *session;
AVCaptureConnection *conn;
AVCaptureMovieFileOutput *movieFileOutput;
NSMutableArray *connectedDevices;
BOOL isVerbose;
NSMutableArray *connectedDevices;
BOOL isVerbose;
NSString *filePath;
}

//
Expand Down Expand Up @@ -62,7 +64,6 @@
*/
-(void)listConnectedDevices;


/**
* Get default generated filename
*/
Expand All @@ -89,7 +90,12 @@
*
* @return BOOL
*/
-(BOOL)startSession:(AVCaptureDevice *)device filePath:(NSString *)path recordingDuration:(NSNumber *)recordSeconds encodingPreset:(NSString *)encodingPreset delaySeconds:(NSNumber *)delaySeconds noAudio:(BOOL)noAudio;
-(BOOL)startSession:(AVCaptureDevice *)device recordingDuration:(NSNumber *)recordSeconds encodingPreset:(NSString *)encodingPreset delaySeconds:(NSNumber *)delaySeconds noAudio:(BOOL)noAudio;

/**
* Delegates togglePauseRecording to movieFileOutput, with SIGINT value from handler
*/
-(void)togglePauseRecording:(int)sigNum;

/**
* Adds an audio device to the capture session, uses the audio from chosen video device
Expand Down
20 changes: 16 additions & 4 deletions videosnap/main.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
VideoSnap *videoSnap;

/**
* signal interrupt handler
* signal interrupt handler Ctrl+c
*/
void SIGINT_handler(int signum) {
if (!isInterrupted && [videoSnap isRecording]) {
Expand All @@ -26,23 +26,35 @@ void SIGINT_handler(int signum) {
}
}

/**
* signal interrupt handler Ctrl+z
*/
void SIGSTP_handler(int signum) {
if ([videoSnap isRecording]) {
[videoSnap togglePauseRecording:signum];
}
}

/**
* main
*/
int main(int argc, const char * argv[]) {

isInterrupted = NO;

// setup int handler for Ctrl+C cancelling
// setup int handlers
// Ctrl+C cancels
// Ctrl+Z pause/resume
signal(SIGINT, &SIGINT_handler);
signal(SIGTSTP, &SIGSTP_handler);

// C args as NSArray
NSMutableArray *args = [[NSMutableArray alloc] initWithCapacity: argc];
for (int i = 0; i < argc; i++) {
[args addObject: [NSString stringWithCString: argv[i] encoding: NSUTF8StringEncoding]];
}

videoSnap = [[VideoSnap alloc] initWithVerbosity:([args indexOfObject:@"-v"] != NSNotFound)];
videoSnap = [[VideoSnap alloc]
initWithVerbosity:([args indexOfObject:@"-v"] != NSNotFound)];

return [videoSnap processArgs: args];
}
3 changes: 2 additions & 1 deletion videosnap/videosnap.1
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ videosnap will capture video and audio from the first found device at 30fps with
a Medium quality preset and a short (0.5s) warm-up delay.
.Pp
If no duration is specified, videosnap will record until you cancel with [Ctrl+c]
You can pause (and resume) recording with [Ctrl+z].
.Pp
You can also use
.Nm
Expand Down Expand Up @@ -76,7 +77,7 @@ No known bugs. Please report any issues here: https://github.com/matthutchinson/
.Sh HISTORY \" Document history if command behaves in a unique manner
.Bl -tag -width -indent
.It 0.0.8
2021-Oct-25 Default filename now includes a date/time stamp
2021-Oct-27 Default filename postfixed with timestamp, Ctrl+z to pause/resume capture
.It 0.0.7
2021-Oct-18 Fix issues with connected iOS device discovery and build/test on M1 arch
.It 0.0.6
Expand Down
22 changes: 17 additions & 5 deletions videosnap/videosnap.m
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ - (int)processArgs:(NSArray *)arguments {

// argument defaults
AVCaptureDevice *device;
NSString *filePath;
NSString *encodingPreset = DEFAULT_ENCODING_PRESET;
NSNumber *delaySeconds = [NSNumber numberWithFloat:DEFAULT_RECORDING_DELAY];
NSNumber *recordingDuration = nil;
Expand Down Expand Up @@ -177,7 +176,6 @@ - (int)processArgs:(NSArray *)arguments {

// start capturing video, start a run loop
if ([self startSession:device
filePath:filePath
recordingDuration:recordingDuration
encodingPreset:encodingPreset
delaySeconds:delaySeconds
Expand All @@ -186,7 +184,7 @@ - (int)processArgs:(NSArray *)arguments {
if(recordingDuration != nil) {
console("Started capture...\n");
} else {
console("Started capture (ctrl+c to stop)...\n");
console("Started capture (ctrl+c to stop, ctrl+z to pause) ...\n");
}
[[NSRunLoop currentRunLoop] run];
} else {
Expand Down Expand Up @@ -299,7 +297,6 @@ - (AVCaptureDevice *)deviceNamed:(NSString *)name {
* Start a capture session on a device, saving to filePath for recordSeconds
*/
- (BOOL)startSession:(AVCaptureDevice *)videoDevice
filePath:(NSString *)filePath
recordingDuration:(NSNumber *)recordingDuration
encodingPreset:(NSString *)encodingPreset
delaySeconds:(NSNumber *)delaySeconds
Expand Down Expand Up @@ -344,7 +341,7 @@ - (BOOL)startSession:(AVCaptureDevice *)videoDevice
// set capture frame rate (fps)
int32_t fps = DEFAULT_FRAMES_PER_SECOND;
verbose("(set capture framerate to %i fps)\n", fps);
AVCaptureConnection *conn = [movieFileOutput connectionWithMediaType:AVMediaTypeVideo];
conn = [movieFileOutput connectionWithMediaType:AVMediaTypeVideo];
if([conn isVideoMinFrameDurationSupported]) {
conn.videoMinFrameDuration = CMTimeMake(1, fps);
}
Expand Down Expand Up @@ -417,6 +414,21 @@ - (BOOL)startSession:(AVCaptureDevice *)videoDevice
return success;
}

/**
* Toggle pause/resume recording to the file
*/
- (void)togglePauseRecording:(int)sigNum {
verbose("\n(caught signal: [%d])\n", sigNum);

if([movieFileOutput isRecordingPaused]) {
fprintf(stderr, "\nResuming capture ...\n");
[movieFileOutput resumeRecording];
} else {
fprintf(stderr, "\nPausing capture ... (ctrl+z to resume, ctrl+c to stop)\n");
[movieFileOutput pauseRecording];
}
}

/**
* Adds an audio device to the capture session, from video device or first available
*/
Expand Down

0 comments on commit a8db19f

Please sign in to comment.