gardenear-api / app.py
Ippili7's picture
Update app.py
1c81eae verified
from flask import Flask, request, jsonify
from birdnetlib import Recording
from birdnetlib.analyzer import Analyzer
from datetime import datetime
import tempfile, os, subprocess
app = Flask(__name__)
print("Loading BirdNET model...")
analyzer = Analyzer()
print("BirdNET model loaded.")
@app.route('/health', methods=['GET'])
def health():
return jsonify({'status': 'ok', 'model': 'BirdNET-Analyzer'})
@app.route('/analyze', methods=['POST'])
def analyze():
if 'audio' not in request.files:
return jsonify({'error': 'No audio file provided'}), 400
audio_file = request.files.get('audio')
lat = float(request.args.get('lat', 0))
lon = float(request.args.get('lon', 0))
# Save incoming .m4a to temp file
with tempfile.NamedTemporaryFile(suffix='.m4a',
delete=False) as tmp_m4a:
tmp_m4a_path = tmp_m4a.name
audio_file.save(tmp_m4a_path)
# Convert .m4a to .wav using ffmpeg
tmp_wav_path = tmp_m4a_path.replace('.m4a', '.wav')
try:
subprocess.run([
'ffmpeg', '-y',
'-i', tmp_m4a_path,
'-ar', '48000',
'-ac', '1',
'-f', 'wav',
tmp_wav_path
], check=True, capture_output=True)
# Run BirdNET on the WAV file
recording = Recording(
analyzer,
tmp_wav_path,
lat=lat,
lon=lon,
date=datetime.now(),
min_conf=0.25
)
recording.analyze()
detections = recording.detections
except subprocess.CalledProcessError as e:
return jsonify({
'error': 'Audio conversion failed',
'detail': e.stderr.decode()
}), 500
except Exception as e:
return jsonify({
'error': 'Analysis failed',
'detail': str(e)
}), 500
finally:
# Always clean up temp files
if os.path.exists(tmp_m4a_path):
os.unlink(tmp_m4a_path)
if os.path.exists(tmp_wav_path):
os.unlink(tmp_wav_path)
if not detections:
return jsonify({'error': 'No species detected'}), 404
top = sorted(detections,
key=lambda x: x['confidence'],
reverse=True)[0]
return jsonify({
'species': top['common_name'],
'scientific_name': top['scientific_name'],
'confidence': round(top['confidence'], 3),
'all_detections': [
{
'species': d['common_name'],
'confidence': round(d['confidence'], 3)
}
for d in detections[:5]
]
})
if __name__ == '__main__':
port = int(os.environ.get('PORT', 7860))
app.run(host='0.0.0.0', port=port)