Another month goes by, another little macOS component was released.
This time, I wanted to have a very simple drop-in view component that takes pictures with the iSight camera of MacBooks or any other connected USB camera device. And if the user wants to crop the picture, I wanted to add that as post-processing.
Thought this would be a common need, but Google wasn't helping much. So I coded this thing myself.
Have a look: https://github.com/CleanCocoa/WebcamSnap
How Taking Pictures with AVFoundation Works
Before I got it working, all the AVFoundation code looked pretty scary. But it's simple, really, when you think about the possibilities of audio and video capturing and processing.
These are the requirements to take a photo with a USB camera using AVFoundation:
- you need a
AVCaptureSessionthat controls the lifetime of the audio and/or video input and/or output;
- you specify output ports of type
AVCaptureOutput, like the
AVCaptureStillImageOutputI use here to grab a single image (instead of video or audio);
- you specify input ports of type
AVCaptureInput, like the
AVCaptureDeviceInputthat takes a
AVCaptureDevice, which in this case is of type
- you add a Core Animation layer (
CALayer) to a preview view using
AVCaptureVideoPreviewLayer(session:)so users see what the camera is showing before they hit the "Take Picture" button.
If things work out well, you have a session that can read video data from your camera device and streams the video signal to the preview. You can shoot photos, also known as "request still images" from the video stream, using
captureStillImageAsynchronously on your
All of this setup is encapsulated in the
Webcam object of my library. (links to the version of v1.0.0, no the latest, to prevent dead links in the future).
Hope it helps!
One important user interface part of my latest top-secret project involves a sidebar of buttons. Like a regular toolbar, but taking up less space for chrome, looking more flat, and the user should be able to create toolbar buttons herself.
So while I was mostly sick at home for the last couple weeks, I spent my time cobbling this together. With drag and drop reordering and all.
FatSadebar on GitHub!
I have never written my own custom view component from scratch before. I helped improve KPCTabsControl for Swift 3 when I created TableFlip last year. And of course I participated in a lot of smaller open source projects, too. But I never started from scratch, and that was cool.
Also fun: creating the library's own "logo". Made it feel so much more official.
What's cool about writing a new thing from nothingness is that I had no clue what to do and how to start. This component turned out as rather adventurous mental gymnastics because I had to leave the paths of application development I know so well. I still don't know all the answers; what are best practices? Get something colorful on screen? Customize
drawRect and draw boxes and placeholders? Partition the view into sub-components using Auto Layout from the get go? Is drawing text better handled by
NSTextField labels than
NSAttributedString.draw(in:) or is the overhead too much? (I still don't know the best answer for this.)
Anyway! I ended up putting this together as a library with sample app. There are some unit tests for inserting items into the "fat sidebar", but otherwise I find the drawing and layout related code to be absolutely hideous. Cannot come up with improvements on that front that go beyond cosmetics, though. Maybe later, with more experience.
Junior Bontognali summed up what most people think about most other people – especially after the U.S. presidential election and Dash for iOS going Open Source: people in general are not ready for generous behavior.
Bogdan's Dash for iOS is on GitHub now. One tweet highlighting an ugly if statement got lots of attention. One twitter user suggested cutting off Bogdan's fingers. That's not a real threat, of course. It's just a stupid joke. But suddenly you're in 4th grade again and everyone is making stupid jokes because someone pulled down someone else's pants.
The thing is, Bogdan of Kapeli is too busy to accept pull requests that don't add features. Maybe because testing these for regressions is pretty time consuming without and end-user benefit. Who knows. So he already turned down a pull request that would fix the aforementioned if-statement – and many others.
Dash probably isn't ready for Open Source, either. A Swift library as simple as ReSwift took us over a month to port to Swift 3. Maintenance is time-consuming, no matter how big or small the project. Complaining is stupid and childish, but that's the noise we have to deal with if we don't want to be stupid and childish ourselves.
I don't think everyone's grown-up enough for democracy. I only hear about 3rd wave feminism and presidential elections in the U.S. from YouTube. Junior quoted Evelyn Beatrice Hall, and that applies just nicely to all the hate that's going 'round:
I disapprove of what you say, but I will defend to the death your right to say it.
It seems lots of people with the power to act in public space don't want to defend anything except their own self-loathing and self-interest. (Looking at you, "safe space" discussions.) If you read my previous ramblings about morals, you will notice that I usually point out that bitching doesn't help. It will only strengthen victim mentality. Only doing will improve the situation. That's why I won't stop open-sourcing code and I'm looking forward to getting feedback by amazing people. The majority of not-so-amazing people on the internet have to be filtered out. It's worth the effort to reach the good folks.