EDIT: I don't know why i thought this question was matlab based, but my solution is written with matlab in mind. a quick search showed my the python scikit has otsu's method for automatic thresholding (this is what matlab uses). Other than that I think most of the code is relatively python safe and can easily be translated. My apologies for my error
from skimage import filter
val = filter.threshold_otsu(camera)
END EDIT
Could you threshold the amplitude of the recording? say this is our recording

where we are just plotting
plot(abs(sound))
can we say the chirping is probably above 2? and assume everything below magnitude=2 is just noise? If so, and assuming you have the imageprocessing toolbox, you could
- normalize the audiofile amplitude (between 0-1) needed for next step
- get automatic thresholding of file imageprocessing toolbox function
- find indicies that exceed threshold and say these are bird chirps
the only problem is with sound even with a strong signal, it will usually cross 0 so you would have discontinuities even in the actual bird chirping. Maybe you can add some sort of hysteresis to the masking operation. Like
if the current sample is below the threshold BUT a large percentage of the previous few samples were above the threshold, we will assume this sample is also an interest point
roughly your code would be something like this (im not near a comp with matlab, so this may have slight syntax errors). This is also not very optimized, but maybe it's a springboard for you or others
%% step 1
%we are using magnitude only
my_min = min(abs(soundfile));
my_max = max(abs(soundfile));
%gets sound file magnitude between 0-1 only
normalized_sound_mag = 1/(my_max-my_min) * (abs(soundfile) - my_min);
%% step 2
%get a threshold, we needed the magnitude between 0-1 for this function to work
sound_thresh = graythresh(normalized_sound_mag);
%% step 3
%this vector will store all sample indexes that are interesting
idx_sound = 0;
num_for_hysteresis = 10; %the number of samples to use for hysteresis
hysteresis_percentage = 0.8; %percentage of samples that must be above threshold
%so say in our set of 10, 2 samples are below threshold
%since .8 are above it, we say they are all of interest
%because the way we implement hysteresis we have to skip the first few samples
for (i=num_for_hysteresis:1:length(normalized_sound_mag))
%if we are above thresh, without a doubt save the index
if (normalized_sound_mag(i) > sound_thresh)
idx_sound = [idx_sound, i];
else
%hysteresis check prev samples, creates a boolean vector. 1 means value above thresh, 0 means it was below
samples_above_thresh = normalized_sound_mag(i-num_for_hysteresis:i) > sound_thresh;
%nnz, gets the number of nonzero elements in a matrix
num_prev_samples_above_thresh = nnz(samples_above_thresh);
%if the number of samples in the prev window met our criteria, this current sample
%is probably of interest as well
if (num_prev_samples_above_thresh > hysteresis_percentage * num_for_hysteresis)
idx_sound = [idx_sound, i];
end
end
end
%idx_sound should now have all the indicies f interest, these can now be used
%directly on the original soundclip
we could also use the frequency power and threshold, rather than the sound amplitude, the basic outline would still be the same.