From 7a833894dcb799139bde52a9463f76be9821b85d Mon Sep 17 00:00:00 2001 From: Patrick Baxter Date: Wed, 20 Nov 2024 09:53:55 +1300 Subject: [PATCH] add audio mode settings (#100) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * - Updated bootstrap-vue-next lib - Updated Vue3 - Reworking mask regions component to disallow self-intersecting regions, and allow an apron so regions can be created slightly outside the camera frame. - Creating wizard steps for manual uploads - Moving device status out of modal * - Fix mask regions tests * - Fix mask regions tests (2, linting) * - Fix sunset/sunrise in visits breakdown - Add more info to mobile device cards in DevicesView * - Fix reference photo component, make it work on mobile. - More responsive layouts for device setup. * - Reference photos are properly scaled when overlaying on CptvPlayer on mobile. - Overflowing tab list component to make longer tabbed nav lists work better on mobile. * - Trail cameras use an appropriate daytime image as an automatic reference image. - Masked regions are now used when adding tracks via the API to ignore tracks that are exclusively inside the masked region. - Use common track rect drawing code for showing tracks for trailcam images. * - Added a dummy track to trailcam recordings where there is no track – the actual track is created the first time a user classification is added. This could be extended to empty CPTV files. * - Styling dummy track * - Fix tests * - Added ability to add a dummy track to a CPTV file that has no tracks. - Automatically add "missed track" tag to CPTV recordings that get manual IDs when they had no tracks. - Poll every 30 seconds when an open recording is still processing, and update UI when processing is complete. * - Improved behaviour when mashing on next/prev buttons in CPTV player very quickly :) * - Fix null settings read in mask-regions API * - Remove stations wording on Dashboard * - API Documentation fix - Add "dummy-track" to tracker version to make it available to processing. * - Don't send algorithm with tracks, use default * - Fix mask-regions api read * - Clone rather than always update in place DeviceHistory entries for adding reference images and mask regions in the same location. - Fix route for Visits modal from activity view to include selected track. * - Clone rather than always update in place DeviceHistory entries for adding reference images and mask regions in the same location. - Fix route for Visits modal from activity view to include selected track. (2) * - Improved responsive layout for activity search - Make search url query driven (WIP) * - Improved responsive layout for activity search - Make search url query driven (WIP) - Fix mask-regions api * - Improved responsive layout for activity search - Make search url query driven - Hack in support for "Animal" class from Megadetector - Show processing progress for visits in API - Reflect processing progress in the UI. * - Add UI to visits when recordings are still processing - Handle scaling DPI when drawing track boxes on trailcam images * - Make sure player inherits query params from parent component - Make recording/visits exports work. * - Don't delete previous reference images * Scale UP: - New bulk querying/reporting API which is *many*, *many* times faster for tag filtering queries over longer periods, esp. when the number of recordings in a project grows. - Thumbnail images on the front-end only get queried when visible. * Scale UP: - CI Tests for new bulk tag mode. * Merge main * Merge main, add all tagModes to improved bulk query. * Address review feedback. * Small fixes * Small fixes (2) * Small fixes (3) * Small fixes (3) * Small fixes (4) * Get rid of legacy bulk recordings query in browse-next * Rework bulk-query, fixing edge-cases and adding more comprehensive tests. Improve UI, lazy loading of activity page. * Fix tests * Fix tests (2) * Make sure we return recordings in the correct order. * Auth. * Make sure we send recording type when querying! * Auth again * Fix recordings export report * Export larger pages to increase export speed, increase limit on server-side * Fix issue where we try to request things from inactive devices and get 403 rejected * Make sure deleted recordings are not included by default in new bulk queries, and add a test for that. Display "leporadae" as "rabbit or hare" * Make sure deleted recordings are not included by default in new bulk queries, and add a test for that. Display "leporadae" as "rabbit or hare" * add recording window and low power mode settings * fix lint * fix for device extract, move settings up * readd location check * Misc fixes and improvements, starting on non-paginated visits API. * Linting * Fix tests * Fix tests (2) * Fix error event logging * Fix cron script permissions for platform usage report * Update docker-compose.yml * Add alert relationship for project-wide alerts * Link to device recordings search from device page * Link to device recordings search from device page - Fix earliest time detection for location recording results * Add ability for the user to manage their own email alerts via browse-next UI. * Linting * Fix tests * Improve device -> recordings button appearance on mobile. * Improve service report email, improve alert email * Service email should only be for the last 24 hours * Improve formatting of service errors. Make audio recordings export include cacophony index column. * Make stopped alerts work for thermal devices we didn't hear from in over 24 hours. Improve formatting of service error emails (stop gmail stripping things?) Fix email link for new-style alert emails. * Fix latest recording times update for groups. * Fix latest recording times update for groups. (2) * Update stopped device email text * Update stopped device email text (2) * Revamp stopped devices notification email. * Skip heartbeat tests (no longer rely on heartbeats for stops) * Make alert animal image link to recording. * Tweak stopped devices logic * Tweak stopped devices logic again * Fleshing out daily/weekly digest emails + user preferences. * add fox tag * Daily+weekly digest emails. Store user timezone info * Add missing tag icons. * Add missing tag icons. (2) * Add fox tag * Add ability to hide false-trigger tracks in Recording View. * White outlines around email tag classification icons so that they show up in dark-mode contexts. * - Improve thumbnail selection in recordings view. - Fix stopped devices query - Add aussie tags to classifications. * - Diagnostics * fix device settings * fix time format in settings * - Adjust stopped device query * - Add ability for super-users to view any group they're not already part of (as an admin user) * - Implement deletion of recordings in browse-next and tweak deletion API to update book-keeping for group and stations lastRecordingTimes. * - Modify locations query to be able to return only locations that don't have zero recordings associated with them, so that deleting the last recording in a location allows that location to be hidden. * - Do latest time fixups for bulkDelete API too. * - Fix tooltips for activity search * - Fix local saving of view false-triggers setting when viewing as a super-user * - Fix hiding of AI false-trigger tags for tracks where there is a user non-false-trigger tag. * - Fix requests for tracks that are user-created and don't have thumbnails. * - Fix user settings persistence * - Fix issue with removing track tags twice. * - Cosmetic tweak – images that fail to load. * - Fix thumbnail selection code. * - Fix display of sunset/sunrise times in visits breakdown for 24/7 cameras. * - Fix date offsets for digests * - Fix date offsets for digests * - Fix date offsets for digests * - Fix date offsets for digests (2) * - Remove beta version wording, add additional filter events * - Fixes for digest email timings and thumbnail selection. * - Allow viewing live thumbnails and cptv recordings in local dev mode. - Add track replay button to tagging view. - Hide audio mode stuff for now. * - Fix unitVersion grouping in daily service error emails. * - Linting * - Additional options for finding a project to view as a super-user * fix to make update device settings invariant * only update if changed * - Complete reset password flow for browse-next. * - Complete reset password flow for browse-next. - Add cypress ui tests for reset password flow. * - Make project switcher work better - Properly reset activity search when projects are switched (WIP) * - Fix linting errors * - Fix broken activity lists - Fix weirdness with project switching (when on activity page) * - Fix CPTV player resizing when browser window is very short vertically, but has a desktop width breakpoint. - Fix date field not being populated when on activity page and page refreshed. * - Fix type import * - Updated device view, device "dashboard" WIP * - Updated device view, device "dashboard" WIP (2) * - Fix visitContext filtering on dashboard. * - Fix recording window length calulation for absolute recordindg windows. - Fix display of visits activity search description if a device was previously filtered on. * - In daily/weekly digest emails, try to fall back to another parent class icon if species icon for tag is not found. * - Improve thumbnail selection for recordings list. * - Improve pathological cases of recording search where there are many many recordings in a project over a long time span, and the user wants to search over "all time". To handle this case, start searching over a max time window of 3 months on the API side, and progressively widen that search until there are no results left or the limit has been reached. * - Handle recordings export where there are (legacy) recordings without a location. * - Abort in-flight requests if multiple searches are done in quick succession to keep state correct. - Script to fixup latest recording times - Fix locations table view - Fix incorrect thumbnail selection in recordings activity search - Don't sync activity search context when we enter a recording. - Don't try to load tag-icons in track tagger view unless the tagging interface is actually expanded. * - Fix station-related tests to not use status-recording length test recordings - Add missing recording labels. * - When we delete the last recording that isn't a status recording, properly fixup last recording times. * - Handle aborted activity search queries more gracefully in the UI. * - Handle aborted activity search queries more gracefully in the UI. (2) * - Fix recording export length truncation when using non-advanced export * - Fix recording export length truncation when using non-advanced export (2) * add device sync-settings to browse-next * - Fixes to dashboard showing non-predator visits and locations - Fix for unselect locations in dashboard - Remove unused dashboard view options. - Add a 'time-sensitive' param to the recordings query, to return from slower queries after a time-out, as long as there are some results gathered. This will make the UI appear more responsive for sparse queries over longer time periods. - Add ability to go to activity for locations from locations page for both visits and recordings scoped to the given location. * - Make max-zoom on maps be not quite as zoomed in (15), since sometimes tiles aren't available for the max zoom level of 16. * - Tidy locations page some more * fix custom recording windows * - Change page size calculation for recordings search. * - Add a script to fixup device history settings corruption by ratThresh script, and fix ratThresh script so that it doesn't nuke settings. * - Make ratThresh script only update device settings if there are new human tagged rodents. * - Make ratThresh script only update device settings if there are new human tagged rodents (2) * remove loction from device history settings. Remove poweron/off for tc2 * - Adding test coverage for device-settings * - Make sure location specific device settings get purged when creating a new station for a device, while previously set device recording window and recording settings get retained. * minor fix on settings api, handle no settings in browse next * - Fix tagged recording query - Set lastConnectionTime to null if newer recordings are uploaded via sidekick so that we see a device as being "offline" from that point. - Fix device settings update in place issue. * - Sync changes with upstream. * - Remove ratthreshold debug code * - Fix UI tests * - Moving settings sync UI to device setup tab (WIP) - Adding flag to get latest *synced* settings - Add tests to confirm/sync settings, and to test getting latest synced settings. * - Moving settings sync UI to device setup tab - Adding flag to get latest *synced* settings - Add latest battery info to devices listing, device diagnostic page, and link to device page from recording view. * - Moving settings sync UI to device setup tab - Adding flag to get latest *synced* settings - Add latest battery info to devices listing, device diagnostic page, and link to device page from recording view. * - Add spinner while saving window settings * - Fix lastActiveTime for stations when recordings are uploaded from Devices * - Better relative time and layout formatting for Locations view. - Update to Vue 3.5 * - Add device events listing for super-users. - Add API end-points for getting all known event types, and for all known event types for a given device in the last month. * - Fix clearing event filter * - Better format nested event item details. * - Fix battery level caching bug for aborted api requests * - Add ability to rename locations that need renaming if the current user is an admin of the project. * - Add ability to rename locations that need renaming if the current user is an admin of the project (2). * update to match browse-next, fix getting settings * - Add known device locations to audio files that are missing location until we get that information embedded in audio metadata * - Fix UI tests * - Fix merge * - Fix CptvPlayer overlay when browser has pixelRatio < 1.0 (zoomed out) * - Various cosmetic fixes to browse next for mobile viewports. * Use github actions instead of travis * Update dockerhub login * Install docker compose * - Added new versions of cptv-decoder - Added m4a metadata extraction to uploads * - Added new versions of cptv-decoder - Added m4a metadata extraction to uploads (2) * - Fix test * - Remove vestiges of unused vue-multiselect. * - Bump cptv-player-vue version * - Bump cptv-player-vue version (2) * - Only set device active when getting a new recording uploaded via sidekick if it's currently inactive, and there's no active instance of that device elsewhere in the system. * - Fix log warning. * - Fix vie build error? * - Update eslint on browse-next - Add tests for verifying uploaded audio files. * - Parallelize github actions jobs - Fix date range picker - Hopefully fix Vite build errors * - Add logging to release build script * - Add logging to release build script (2) * - Add IS_CI_ENV to release job. * - Fix sub-species use of icons in digest emails * - Clicking a visit should always select+display the first recording in the visit with a track matching the visit classification. * - Split api integration tests into two batches of roughly equal time to enable us to parallelise the test run into two jobs in CI, decreasing total CI time. * - Split api integration tests into two batches of roughly equal time to enable us to parallelise the test run into two jobs in CI, decreasing total CI time. (2) * - Check pwd for tests. * - Actually add moved spec files! * - Re-balance test batches * - Clean up test external type imports - Remove unused tests - Use matrix strategy to run test batches * - Use npm cache * - Use npm ci instead of npm install to take advantage of github actions cache (once run against `main`) * - More comprehensive testing of deleted, inactive and reassigned devices. - Fix behaviour when re-assigning a device, so we don't orphan recordings. - Fix handling of inactive devices in browse-next. * - Before re-registering a device in tests, make sure it has at least one recording so that the previous device is set inactive rather than deleted. * - Fix routing * - If moving a device from the new group, soft delete all recordings made in new group, and also delete old device. * - Show when there are no events for device in the last month * - Only check battery levels on devices we think aren't stopped or offline. * - Fix device status image retrieval. * - Sometimes we need to keep asking for frames till we get a good one on cptv single image component. * - Sometimes we need to keep asking for frames till we get a good one on cptv single image component. * add audio mode settings * - Fix latest status recording not selecting device. * - Force use of "audio/mp4" mime-type for .aac files. * - Fix request host headers if they get re-written to default to browse-next - Always allow showing device recordings, even when there's no current location set. --------- Co-authored-by: jon Co-authored-by: Abra Co-authored-by: cam --- api/Server.ts | 6 + api/api/V1/recordingUtil.ts | 3 + browse-next/src/api/Device.ts | 1 + .../src/components/CptvSingleFrame.vue | 2 + .../src/components/DeviceRecordingSetup.vue | 337 +++++++++++++++++- browse-next/src/views/DevicesView.vue | 9 +- browse-next/vite.config.ts | 8 +- browse/src/api/Device.api.ts | 34 ++ browse/src/components/Devices/DeviceInfo.vue | 93 ++++- types/api/device.d.ts | 12 + 10 files changed, 484 insertions(+), 21 deletions(-) diff --git a/api/Server.ts b/api/Server.ts index 7b6f3065..5ff370c1 100755 --- a/api/Server.ts +++ b/api/Server.ts @@ -149,6 +149,12 @@ const checkS3Connection = async (): Promise => { "Access-Control-Allow-Headers", "where, offset, limit, Authorization, Origin, X-Requested-With, Content-Type, Accept, Viewport, if-none-match, cache-control" ); + + // NOTE: We've seen an instance where the HOST request header is rewritten by the client, which would otherwise break + // some things. If the host is unknown, default to browse-next. + if (!request.headers.host.includes("cacophony.org.nz")) { + request.headers.host = "https://browse-next.cacophony.org.nz"; + } next(); }); await initialiseApi(app); diff --git a/api/api/V1/recordingUtil.ts b/api/api/V1/recordingUtil.ts index ad4c51da..1d9b0ea1 100755 --- a/api/api/V1/recordingUtil.ts +++ b/api/api/V1/recordingUtil.ts @@ -1356,6 +1356,9 @@ export function signedToken( export const guessMimeType = (type, filename): string => { const mimeType = mime.getType(filename); if (mimeType) { + if (mimeType === "audio/x-aac") { + return "audio/mp4"; + } return mimeType; } switch (type) { diff --git a/browse-next/src/api/Device.ts b/browse-next/src/api/Device.ts index 691c257a..5ccf122c 100644 --- a/browse-next/src/api/Device.ts +++ b/browse-next/src/api/Device.ts @@ -341,6 +341,7 @@ export const getLatestStatusRecordingForDevice = ( params.append("max-results", "1"); params.append("types", "thermal"); params.append("include-false-positives", true.toString()); + params.append("devices", deviceId.toString()); if (use2SecondRecordings) { params.append("status-recordings", true.toString()); } diff --git a/browse-next/src/components/CptvSingleFrame.vue b/browse-next/src/components/CptvSingleFrame.vue index 6895223c..4914e3d0 100644 --- a/browse-next/src/components/CptvSingleFrame.vue +++ b/browse-next/src/components/CptvSingleFrame.vue @@ -120,6 +120,8 @@ const loadRecording = async () => { ); frameData.value = new ImageData(buffer, 160, 120); renderFrame(); + } else { + break; } } } diff --git a/browse-next/src/components/DeviceRecordingSetup.vue b/browse-next/src/components/DeviceRecordingSetup.vue index 6006131e..3f14cab6 100644 --- a/browse-next/src/components/DeviceRecordingSetup.vue +++ b/browse-next/src/components/DeviceRecordingSetup.vue @@ -4,11 +4,13 @@ import { selectedProjectDevices } from "@models/provides.ts"; import type { ApiDeviceHistorySettings, ApiDeviceResponse, + AudioModes, } from "@typedefs/api/device"; import { useRoute } from "vue-router"; import type { DeviceId } from "@typedefs/api/common"; import type { LoadedResource } from "@api/types.ts"; import { + getDeviceModel, getDeviceNodeGroup, getSettingsForDevice, updateDeviceSettings, @@ -16,13 +18,12 @@ import { import Datepicker from "@vuepic/vue-datepicker"; import { projectDevicesLoaded } from "@models/LoggedInUser.ts"; import { resourceIsLoading } from "@/helpers/utils.ts"; -import { DeviceType } from "@typedefs/api/consts.ts"; type Time = { hours: number; minutes: number; seconds: number }; const devices = inject(selectedProjectDevices) as Ref< ApiDeviceResponse[] | null >; const route = useRoute(); -const saltNodeGroup = ref>(null); +const deviceModel = ref>(null); // Device Settings const settings = ref>(null); const syncedSettings = ref>(null); @@ -53,9 +54,9 @@ const device = computed(() => { const settingsLoading = resourceIsLoading(settings); const lastSyncedSettingsLoading = resourceIsLoading(lastSyncedSettings); -const nodeGroupInfoLoading = resourceIsLoading(saltNodeGroup); +const nodeGroupInfoLoading = resourceIsLoading(deviceModel); const isTc2Device = computed(() => { - return (saltNodeGroup.value || "").includes("tc2"); + return deviceModel.value === "tc2"; }); const defaultWindows = { powerOn: "-30m", @@ -152,8 +153,8 @@ const loadResource = async ( const initialised = ref(false); onBeforeMount(async () => { await projectDevicesLoaded(); - await loadResource(saltNodeGroup, () => getDeviceNodeGroup(deviceId.value)); await loadResource(settings, fetchSettings); + await loadResource(deviceModel, () => getDeviceModel(deviceId.value)); initialised.value = true; if (settings.value && !settings.value.synced) { // Load last synced settings @@ -283,6 +284,233 @@ const customRecordingWindowStop = computed