blakeblackshear / frigate

NVR with realtime local object detection for IP cameras
https://frigate.video
MIT License
19.02k stars 1.74k forks source link

Download a custom length recording #2369

Closed mr6880 closed 1 year ago

mr6880 commented 2 years ago

This suggestion relates to recordings collected by Frigate and the ability to download them.

Frigate is great for detecting objects and allowing those detections to be downloaded. Frigate is also great for recording 24/7, and allowing a user to go to specific points of the 24/7 hour recording using its database of detections.

I've more than once found myself wanting to download footage from outside of the detection period. For example, the events leading up to a detection that cannot be detected by Frigate (lights turning on some time before an object emerges, screaming/shouting/tyre screeching audio in the distance before an object emerges etc) or if an object hides from the camera, and then re-emerges some time later.

Continuous, unbroken recordings may also be crucial for law enforcement purposes, if the Police required a continuous recording as evidence (although shamefully, the Police in my area tend to record the screen with their phone, rather than collecting raw footage).

My suggestion would be to somehow implement the ability to download specific parts of a 24/7 recording, or create custom events between specific times, which would then allow a user to download those recordings (perhaps a 10 minute clip, crossing between one hour and another). This would allow a user to save important evidence in a quick and efficient manner, directly from the Frigate GUI.

blakeblackshear commented 2 years ago

The endpoint already exists, it just needs a UI: https://github.com/blakeblackshear/frigate/blob/master/frigate/http.py#L559

mr6880 commented 2 years ago

That endpoint works exceptionally well.

hmakmur commented 2 years ago

I would like to second this feature request. I was surprised to find out that I could save the Clips but NOT the Recordings. Please add ability to Download Recordings. Thank you.

mr6880 commented 2 years ago

I've been thinking about this a little more. A starting place could be a simple URL builder, where you select the camera and start & end times, and it would then produce a URL to click like: /back/start/1638829800/end/1638830100/clip.mp4

Obviously the above is a very simple implementation, and you'd want things like dynamic clip names and selectable start/end times to be based on availability, to prevent downloading footage that isn't available etc. It also requires some thought as to where/how exactly to implement it in the UI - on the camera page next to "Debug" perhaps, or in the recordings timeline page somehow? I'm sure lots of people would have their own ideas as to how it should be done.

At present, manually creating a URL with camera name and epoch times as above is a good workaround if you're desperate for footage. It's actually super fast compared to the old NVRs I'm used to. Have you tested that method hmakmur? If so, what do you think?

hmakmur commented 2 years ago

Simple URL is fine. Anything that allows me to download the recording is fine. I can edit the video afterward. Is there a way to download via URL already?

blakeblackshear commented 2 years ago

The URL already exists and works. /api/back/start/1638829800/end/1638830100/clip.mp4 The start and end times are in unix timestamps. You can convert here: https://www.epochconverter.com/

mr6880 commented 2 years ago

Definitely. Just hit http://frigate_IP:5000/api/camera_name/start/1638829800/end/1638830100/clip.mp4 in your web browser, and it should return a downloadable 5 minute video clip from your camera recording.

Works very well.

hmakmur commented 2 years ago

Thank you. I did not know this feature exist. This resolves my immediate issues downloading recording.

BBaoVanC commented 2 years ago

Don't know if this has already been mentioned somewhere, but it would be nice to have some section where you could create "user events" or user-defined clips. Then maybe there could be a config option to prevent the user defined clips from ever expiring.

Maybe even there could be an option for object detection clips to be saved too, so they don't expire.


Also, I'm using the API endpoint that @blakeblackshear sent, but it looks like the temporary files that endpoint generates never get deleted from /tmp/cache, so if I try and download too much (one hour at a time to prevent timeout, but many hours total), then the cache eventually fills up and I can't download any more until I restart frigate.

Edit: actually, it looks like the files get deleted, but according to df -h inside the container, the disk used in /tmp/cache doesn't go down. Weird.

NickM-27 commented 2 years ago

@BBaoVanC there's a pinned issue for this and I have a WIP implementation https://github.com/blakeblackshear/frigate/pull/3184

Then maybe there could be a config option to prevent the user defined clips from ever expiring.

I think this would just utilize the existing retain field, could be set by the create call

NickM-27 commented 2 years ago

Also, I'm using the API endpoint that blakeblackshear sent, but it looks like the temporary files that endpoint generates never get deleted from /tmp/cache, so if I try and download too much (one hour at a time to prevent timeout, but many hours total), then the cache eventually fills up and I can't download any more until I restart frigate.

Edit: actually, it looks like the files get deleted, but according to df -h inside the container, the disk used in /tmp/cache doesn't go down. Weird.

I tried this, it gets deleted and after a few minutes the space is cleared back out, do you see the same?

BBaoVanC commented 2 years ago

It's been about 20 hours since then and it does look like the space eventually went down. I was already seeing the files deleted within a minute or two, but df -h inside the container wasn't reflecting that. I wonder if maybe it's just some visual bug with df. I'll probably upgrade to the latest pre-release now anyways so I can try out the new experimental timeline player.

artlov commented 2 years ago

I found this thread because there was also a need to copy one-hour clips from the cameras to an external disk for archiving with little effort or too much scripting. But I get a 500 Internal error because I have /tmp/cache mounted by tmpfs and it's 1GB in size and an hour long temporary file can't fit there. Happiness was so close :)

NickM-27 commented 2 years ago

I found this thread because there was also a need to copy one-hour clips from the cameras to an external disk for archiving with little effort or too much scripting. But I get a 500 Internal error because I have /tmp/cache mounted by tmpfs and it's 1GB in size and an hour long temporary file can't fit there. Happiness was so close :)

Instead of using the mp4 endpoint you could use the .m3u8 endpoint and use something like VLC or ffmepg to download it to an mp4 directly which would circumvent the cache

BBaoVanC commented 2 years ago

I found this thread because there was also a need to copy one-hour clips from the cameras to an external disk for archiving with little effort or too much scripting. But I get a 500 Internal error because I have /tmp/cache mounted by tmpfs and it's 1GB in size and an hour long temporary file can't fit there. Happiness was so close :)

Instead of using the mp4 endpoint you could use the .m3u8 endpoint and use something like VLC or ffmepg to download it to an mp4 directly which would circumvent the cache

So should Iuse the same API endpoint, but instead of clip.mp4, use clip.m3u8? And then just use ffmpeg to convert to mp4?

NickM-27 commented 2 years ago

So should Iuse the same API endpoint, but instead of clip.mp4, use clip.m3u8? And then just use ffmpeg to convert to mp4?

You would use https://docs.frigate.video/integrations/api#get-vodcamerastartstart-timestampendend-timestampindexm3u8

ffmpeg or https://www.easefab.com/resource/vlc-convert-m3u8-to-mp4.html will get it working

mmlody commented 2 years ago

error from nginx when tryng to get long recording (~3hr)

image

first error was no space left on device ( /tmp/cache - because in docker instalation of frigate "default" /tmp/cache is set as 1GB of RAM ) when first time try to get this long recording

is know any good method to get record in one file from lareger period of time (hours not minutes) ?

NickM-27 commented 2 years ago

error from nginx when tryng to get long recording (~3hr)

image

first error was no space left on device ( /tmp/cache - because in docker instalation of frigate "default" /tmp/cache is set as 1GB of RAM ) when first time try to get this long recording

is know any good method to get record in one file from lareger period of time (hours not minutes) ?

Use the stream URL (index.m3u8) and use something like VLC to download it

mmlody commented 2 years ago

download in VLC is same as open stream (M3U) and convert this stream to MP4 ?

NickM-27 commented 2 years ago

download in VLC is same as open stream (M3U) and convert this stream to MP4 ?

I believe so

artlov commented 2 years ago

I've solved it with crontab script:

YMDH1=$(date -d 'now -1 hour' +'%Y-%m/%d/%H')
YMDH2=$(date -d 'now -1 hour' +'%Y-%m-%d-%H')
URL='http://192.168.2.4:5000'
OUTDIR='/syno/recordings/frigate_archive'

# cams list from frigate api:
mycam=$(curl -s ${URL}/api/config |jshon -e cameras -k)
declare -a camarray=($mycam)

i=0
while [[ ${camarray[$i]} ]]; do
    ffmpeg -y -i ${URL}/vod/${YMDH1}/${camarray[$i]}/master.m3u8 -c copy ${OUTDIR}/${camarray[$i]}-${YMDH2}.mkv
    i=$[$i+1]
done
mmlody commented 2 years ago

I try get only one file ~4hrs of recordings for my need URL (in my opinion) must have this syntax:

http://localhost:5000/vod/front-gora/start/1664902800/end/1664920740/index.m3u8

where start and stop syntax are outputs from:

start timestamp is output from: date -d '10/04/2022 19:00:00' +'%s' end timestamp is output from date -d '10/04/2022 23:59:00' +'%s'

and I stil get only this error http://localhost:5000/vod/front-gora/start/1664902800/end/1664920740/index.m3u8: Server returned 5XX Server Error reply

frigate under this URL workng, script from artlov working

how to get one large recording from frigate ? is it possible ?

mew1033 commented 2 years ago

I'm also getting a 503 error when trying to use this endpoint. Checking the error.log, I see:

2022/10/09 22:35:48 [error] 200#200: *2546 media_set_parse_durations: invalid number of elements in the durations array 2701 while sending to client, client: 172.28.0.240, server: , request: "GET /vod/camera_name/start/1665244800/end/1665271800/index.m3u8 HTTP/1.1",
hpricey commented 1 year ago

Are there any plans to add this functionality to the UI as a complete feature @blakeblackshear? Would be great to have a solution that's as good as the events 'download clip'. I guess this would use a slider/timeline to set start and end points?

blakeblackshear commented 1 year ago

Yes. It will probably be a part a future release where the recordings viewer is revamped. Currently, the mp4 endpoint is written to the cache location and you can easily crash the system by exporting a file that's too long. This will need to be fixed too.

DrSpaldo commented 1 year ago

I would also love this feature. It makes it quite hard to download larger clips that are not a specific event without this feature. Thanks

KennyStier commented 1 year ago

Made a quick bash script for downloading custom clips. 3 hrs seems to be the maximum length, attempting to download clips longer than 3 hrs returns a 503 error. https://gist.github.com/KennyStier/df149aefc7a6084acd926eca3e84acd9

NickM-27 commented 1 year ago

Made a quick bash script for downloading custom clips. 3 hrs seems to be the maximum length, attempting to download clips longer than 3 hrs returns a 503 error.

https://gist.github.com/KennyStier/df149aefc7a6084acd926eca3e84acd9

You can download whatever length you want using the m3u8 endpoint. Using mp4 depends on your cache size and bandwidth of the recording.

blakeblackshear commented 1 year ago

There is an upper limit on the number of segments the VOD endpoints can handle. It will also depend on your disk speed since the VOD module has to read some metadata from each segment when generating the playlist. The maximum length will vary by configuration and hardware.

DrSpaldo commented 1 year ago

Let me start this with two caveats; 1) I stole/used @KennyStier's script to generate my page. 2) I am not a designer and this doesn't look fancy at all. But, so far it is working and is easier than using a script for those who prefer the visual aspect.

Below are the two main files;

index.html: (camera names & descriptions need to be updated)

<!DOCTYPE html>
<html>
<head>
    <title>Frigate Export</title>
    <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <style>
        .ui-datepicker {
            font-size: 0.8em;
        }
    </style>
</head>
<body>
    <form method="post" action="frigate-export.php">
        <label for="camera">Choose your camera:</label>
        <select name="camera" id="camera">
        <option value="camera1">Camera 1</option>
        <option value="camera2">Camera 2</option>
        <option value="camera3">Camera 3</option>
        <option value="camera4">Camera 4</option>
        <option value="camera5">Camera 5</option>
        <option value="camera6">Camera 6</option>
        <option value="camera7">Camera 7</option>
        </select>
        <br>
        <label for="start">Start date and time:</label>
        <input type="text" name="start" id="start" placeholder="Jan 1, 2023 16:20:00">
        <br>
        <label for="end">End date and time:</label>
        <input type="text" name="end" id="end" placeholder="Jan 1, 2023 18:30:00">
        <br>
        <button type="submit">Export</button>
    </form>
    <?php if (!empty($filename)): ?>
        <p>Generated file: <?php echo $filename; ?></p>
    <?php endif; ?>

    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-ui-timepicker-addon/1.6.3/jquery-ui-timepicker-addon.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-ui-timepicker-addon/1.6.3/jquery-ui-timepicker-addon.min.css">
    <script>
        $(document).ready(function() {
            $("#start, #end").datetimepicker({
                dateFormat: "M d, yy",
                timeFormat: "HH:mm:ss",
                showAnim: "slideDown",
                changeYear: true,
                yearRange: "-100:+0",
            });
        });
    </script>
</body>
</html>

frigate-export.php: (server IP/port need to be updated)

<?php
$url = 'http://192.168.1.10:5000';
$outdir = './archive';
$filename = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $camera = $_POST['camera'];
    $startstring = $_POST['start'];
    $endstring = $_POST['end'];

    if (!empty($camera) && !empty($startstring) && !empty($endstring)) {
        $start = strtotime($startstring);
        $end = strtotime($endstring);
        $startname = date('Y-m-d_H-i-s', $start);

        $command = "ffmpeg -y -i {$url}/vod/{$camera}/start/{$start}/end/{$end}/index.m3u8 -c copy {$outdir}/{$camera}-{$startname}.mp4";

        exec($command, $output, $return_var);

        if ($return_var === 0) {
            $filename = "{$camera}-{$startname}.mp4";
            $filepath = $outdir . '/' . $filename;
            echo 'Export completed successfully. File: <a href="' . $filepath . '" target="_blank" rel="noopener noreferrer">' . $filename . '</a>';
        } else {
            echo 'Export failed.';
        }
    }
}
?>

Notes; I am running nginx in docker. The index.html & frigate-export.php files are in one of the web hosting files, I created a sub-folder called archive. This folder is where all the exported clips go into. You need to have ffmpeg installed and I also have the two attached files daterangepicker.css & daterangepicker.js due to the visual date selection. daterangepicker.zip

Hopefully this makes sense and may be helpful for someone else...

DrSpaldo commented 1 year ago

@NickM-27 @blakeblackshear I have no idea how to do PR's or play with the code in Frigate itself. I am not sure if there would be an easy way to plug this code into frigate itself?

blakeblackshear commented 1 year ago

There isn't an easy way to plug php or one off pages into Frigate directly. It will be less effort to add this functionality to frigate the way we intend to.

tjhowse commented 1 year ago

Would the project be interested in an export UI in a collapsible header underneath the video object on a camera's recording page composed of two timedate pickers, and "Set Clip Start", "Set Clip End" and "Export Clip" buttons? Clicking a "Set Export..." button loads the timecode (plus recording start time) from the video object into the corresponding picker.

This UI would be functional, but not particularly snazzy. It would also have poor UX for exporting clips that straddle an hour boundary. I'm making the assumption that it's easy to read out the start datetime and timecode of the video object.

DrSpaldo commented 1 year ago

I would be interested in having ANY type of export function in the interface. It is insane that it is not included...

blakeblackshear commented 1 year ago

It's already been implemented and merged for 0.13

tjhowse commented 1 year ago

Amazing news! Thanks very much.

DrSpaldo commented 1 year ago

It's already been implemented and merged for 0.13

Great news

jonwork88 commented 1 year ago

Thats a great addition - I will use it a lot. When will 0.13 be released? Im on "stable" using an Unraid Docker. "Stable" on Unraid is 0.12.1

Loooove this program btw!!

DrSpaldo commented 1 year ago

It's already been implemented and merged for 0.13

I've just moved my server to a new machine and unfortunately my page above that I created isn't working anymore. @blakeblackshear @NickM-27 Is there any easy way to install the current Frigate beta that includes the export function?

NickM-27 commented 1 year ago

You can install the dev version, but need to make sure you read the docs first.

DrSpaldo commented 1 year ago

You can install the dev version, but need to make sure you read the docs first.

hit me

NickM-27 commented 1 year ago

https://github.com/blakeblackshear/frigate/pull/6262

Packages are available in the side bar.

DrSpaldo commented 1 year ago

Thanks @NickM-27 . When I change image: ghcr.io/blakeblackshear/frigate:stable to image: ghcr.io/blakeblackshear/frigate:dev it doesn't work. I am guessing I am doing it wrong?

DrSpaldo commented 1 year ago

I figured it out, for those playing at home you need to include the build. Ie.

image: ghcr.io/blakeblackshear/frigate:dev-7c629c1

RobertusIT commented 1 year ago

some know how to download a clip, from an event, and copy or move it, in a folder?

have this script someone?

I wish to move a clip from an event, into a folder in the cloud, i have /mnt/cloud mounted, i only need to understand or a script, that download clip from event, I guess via API, and upload in /mnt/cloud

NickM-27 commented 1 year ago

there is an existing api for this https://docs.frigate.video/integrations/api#get-apieventsidclipmp4

RobertusIT commented 1 year ago

there is an existing api for this https://docs.frigate.video/integrations/api#get-apieventsidclipmp4

I know, with this API, you can see the clip, but how in Home Assistant, have an automation, to have, when there is a motion:

This videoclip, in a folder ?

In first how, so the automation that can do that, i asked this.

And also rename it in folder, because have always name clip.mp4, so overwrite everytime for all events

But in first, i don't understand how to create ad automation that get from a motion for example doorbell camera, the .mp4 clip and move it in /mnt/cloud folder...

NickM-27 commented 1 year ago

I see, that is an HA question not really a frigate question

troykelly commented 10 months ago

there is an existing api for this https://docs.frigate.video/integrations/api#get-apieventsidclipmp4

But that endpoint doesn't work.

Is there anything that works via the API to download video?

tjhowse commented 10 months ago

It does work, in my experience, but only for short clips. When you request an export the server spins up a few threads to create the file for download. If it's longer than a few minutes the overall process doesn't work. At the time I blamed it on the web request timing out.

On Tue, 19 Dec 2023 at 09:20, Troy Kelly @.***> wrote:

there is an existing api for this https://docs.frigate.video/integrations/api#get-apieventsidclipmp4

But that endpoint doesn't work.

Is there anything that works via the API to download video?

— Reply to this email directly, view it on GitHub https://github.com/blakeblackshear/frigate/issues/2369#issuecomment-1861844055, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHWDUJH35VJ6DTIQ7BBQRTYKDFTFAVCNFSM5JIPWDUKU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBWGE4DINBQGU2Q . You are receiving this because you commented.Message ID: @.***>