Browse Source

bugfix, image size and video

main
Domagoj Zecevic 2 days ago
parent
commit
dec61c2a6e
  1. 11
      .claude/settings.local.json
  2. BIN
      footage/20260520/images/A26052016045712.jpg
  3. BIN
      footage/20260520/images/A26052016290210.jpg
  4. BIN
      footage/20260520/record/A260520_153838_153852.265
  5. BIN
      footage/20260520/record/A260520_160454_160509.265
  6. 6
      internal/video/thumb.go
  7. 30
      internal/web/templates/images.html
  8. 20
      internal/web/templates/videos.html
  9. BIN
      testdata/footage/20260101/images/A26010112000001.jpg
  10. BIN
      testdata/footage/20260101/images/A26010112050001.jpg
  11. BIN
      testdata/footage/20260101/record/A260101_120000_120015.265
  12. BIN
      testdata/footage/20260101/record/A260101_120500_120530.265
  13. BIN
      testdata/footage/20260102/images/A26010213000001.jpg

11
.claude/settings.local.json

@ -15,7 +15,16 @@
"Bash(go test ./...:*)",
"Bash(git:*)",
"mcp__aide__*",
"Bash(docker compose build *)"
"Bash(docker compose build *)",
"Bash(ffmpeg -loglevel error -i /home/dzecevic/repos/CamMonitor/testdata/footage/20260101/record/A260101_120000_120015.265 -c:v copy -movflags frag_keyframe+empty_moov -f mp4 /dev/null)",
"Bash(ffmpeg -loglevel error -i /home/dzecevic/repos/CamMonitor/footage/record/A260520_153838_153852.265 -c:v copy -movflags frag_keyframe+empty_moov -f mp4 /tmp/test_stream.mp4)",
"Bash(echo \"exit: $?\")",
"Read(//tmp/**)",
"Bash(ffmpeg -loglevel error -ss 0 -i /home/dzecevic/repos/CamMonitor/footage/record/A260520_153838_153852.265 -vframes 1 -vf scale=160:90:force_original_aspect_ratio=decrease -f image2 -vcodec mjpeg /tmp/test_thumb.jpg)",
"Bash(ffmpeg -loglevel warning -ss 0 -i /home/dzecevic/repos/CamMonitor/footage/record/A260520_153838_153852.265 -vframes 1 -vf scale=160:90:force_original_aspect_ratio=decrease -f image2 -vcodec mjpeg /tmp/test_thumb.jpg)",
"Bash(ffmpeg -loglevel error -i /home/dzecevic/repos/CamMonitor/footage/record/A260520_153838_153852.265 -ss 0 -vframes 1 -vf scale=160:90:force_original_aspect_ratio=decrease -f image2 -vcodec mjpeg /tmp/test_thumb2.jpg)",
"Bash(mv /home/dzecevic/repos/CamMonitor/footage/images/* /home/dzecevic/repos/CamMonitor/footage/20260520/images/)",
"Bash(mv /home/dzecevic/repos/CamMonitor/footage/record/* /home/dzecevic/repos/CamMonitor/footage/20260520/record/)"
]
}
}

BIN
footage/20260520/images/A26052016045712.jpg (Stored with Git LFS)

Binary file not shown.

BIN
footage/20260520/images/A26052016290210.jpg (Stored with Git LFS)

Binary file not shown.

BIN
footage/20260520/record/A260520_153838_153852.265 (Stored with Git LFS)

Binary file not shown.

BIN
footage/20260520/record/A260520_160454_160509.265 (Stored with Git LFS)

Binary file not shown.

6
internal/video/thumb.go

@ -44,8 +44,12 @@ func (c *Cache) Thumbnail(absPath string) ([]byte, error) {
cmd := exec.Command(
c.ffmpegPath,
"-loglevel", "error",
"-ss", "0",
"-i", absPath,
// -ss must come AFTER -i for raw H.265 bitstreams.
// Input seeking (-ss before -i) requires an index that raw streams lack,
// causing "could not seek to position 0.000" and an empty output.
// Output seeking (-ss after -i) decodes from the start and is reliable.
"-ss", "0",
"-vframes", "1",
"-vf", fmt.Sprintf("scale=%d:%d:force_original_aspect_ratio=decrease", thumbnailWidth, thumbnailHeight),
"-f", "image2",

30
internal/web/templates/images.html

@ -25,10 +25,32 @@
</div>
</div>
<div class="relative min-h-0 flex-1 overflow-hidden bg-black">
<img src="{{.Current.RawURL}}" alt="{{.Current.Filename}}" class="h-full max-h-[calc(100vh-15rem)] min-h-[18rem] w-full object-contain">
<a href="/day/{{.Date}}/images?idx={{.PrevIndex}}" class="absolute left-3 top-1/2 -translate-y-1/2 rounded-md bg-slate-950/80 px-3 py-2 text-sm font-medium text-white hover:bg-slate-900">Prev</a>
<a href="/day/{{.Date}}/images?idx={{.NextIndex}}" class="absolute right-3 top-1/2 -translate-y-1/2 rounded-md bg-slate-950/80 px-3 py-2 text-sm font-medium text-white hover:bg-slate-900">Next</a>
<!-- Viewer: fixed height so the image always fits without page scroll. -->
<div class="relative h-[calc(100vh-18rem)] min-h-[16rem] overflow-hidden bg-black">
<!-- object-contain keeps the full image visible; the black bg fills letterbox gaps. -->
<img src="{{.Current.RawURL}}"
alt="{{.Current.Filename}}"
class="h-full w-full object-contain">
<!-- Prev / Next overlays -->
<a href="/day/{{.Date}}/images?idx={{.PrevIndex}}"
class="absolute left-3 top-1/2 -translate-y-1/2 rounded-md bg-slate-950/80 px-3 py-2 text-sm font-medium text-white hover:bg-slate-900">&#8592;</a>
<a href="/day/{{.Date}}/images?idx={{.NextIndex}}"
class="absolute right-3 top-1/2 -translate-y-1/2 rounded-md bg-slate-950/80 px-3 py-2 text-sm font-medium text-white hover:bg-slate-900">&#8594;</a>
<!-- Full-size button: opens raw image in a new tab at original resolution. -->
<a href="{{.Current.RawURL}}"
target="_blank"
rel="noopener"
title="Open full-size image"
class="absolute right-3 top-3 rounded-md bg-slate-950/80 p-2 text-white hover:bg-slate-900">
<!-- expand / external-link icon -->
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round"
d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4
M14 4h6m0 0v6m0-6L10 14" />
</svg>
</a>
</div>
<script>

20
internal/web/templates/videos.html

@ -26,10 +26,22 @@
</div>
</div>
<div class="relative min-h-0 flex-1 overflow-hidden bg-black">
<video data-video-player controls autoplay poster="{{.Current.ThumbURL}}" src="{{.Current.StreamURL}}" class="h-full max-h-[calc(100vh-15rem)] min-h-[18rem] w-full object-contain"></video>
<a href="/day/{{.Date}}/videos?idx={{.PrevIndex}}" data-nav="prev" data-index="{{.PrevIndex}}" class="absolute left-3 top-1/2 -translate-y-1/2 rounded-md bg-slate-950/80 px-3 py-2 text-sm font-medium text-white hover:bg-slate-900">Prev</a>
<a href="/day/{{.Date}}/videos?idx={{.NextIndex}}" data-nav="next" data-index="{{.NextIndex}}" class="absolute right-3 top-1/2 -translate-y-1/2 rounded-md bg-slate-950/80 px-3 py-2 text-sm font-medium text-white hover:bg-slate-900">Next</a>
<div class="relative h-[calc(100vh-18rem)] min-h-[16rem] overflow-hidden bg-black">
<!-- muted: required for autoplay in Chrome/Firefox/Safari without user gesture.
playsinline: prevents iOS Safari from going full-screen on play. -->
<video data-video-player
controls
autoplay
muted
playsinline
poster="{{.Current.ThumbURL}}"
src="{{.Current.StreamURL}}"
class="h-full w-full object-contain"></video>
<a href="/day/{{.Date}}/videos?idx={{.PrevIndex}}" data-nav="prev" data-index="{{.PrevIndex}}"
class="absolute left-3 top-1/2 -translate-y-1/2 rounded-md bg-slate-950/80 px-3 py-2 text-sm font-medium text-white hover:bg-slate-900">&#8592;</a>
<a href="/day/{{.Date}}/videos?idx={{.NextIndex}}" data-nav="next" data-index="{{.NextIndex}}"
class="absolute right-3 top-1/2 -translate-y-1/2 rounded-md bg-slate-950/80 px-3 py-2 text-sm font-medium text-white hover:bg-slate-900">&#8594;</a>
</div>
<script>

BIN
testdata/footage/20260101/images/A26010112000001.jpg (Stored with Git LFS)

Binary file not shown.

BIN
testdata/footage/20260101/images/A26010112050001.jpg (Stored with Git LFS)

Binary file not shown.

BIN
testdata/footage/20260101/record/A260101_120000_120015.265 (Stored with Git LFS)

Binary file not shown.

BIN
testdata/footage/20260101/record/A260101_120500_120530.265 (Stored with Git LFS)

Binary file not shown.

BIN
testdata/footage/20260102/images/A26010213000001.jpg (Stored with Git LFS)

Binary file not shown.
Loading…
Cancel
Save