Skip to content

Commit 6f8db7a

Browse files
authored
Chore/bubbletea refactor (#69)
* Major refactor. Use bubbletea instead of promoptui. Change license to AGPL * Clean up possible memory issues --------- Co-authored-by: Jared.K <3268576+jaredkotoff@users.noreply.github.com>
1 parent a477e50 commit 6f8db7a

File tree

17 files changed

+2057
-730
lines changed

17 files changed

+2057
-730
lines changed

.gitignore

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,32 @@
1-
node_modules
2-
bin
3-
test*
1+
# Binaries and executables
2+
node_modules/
3+
bin/
4+
test*/
45
obs-random-video*
56
*.7z
67
*.exe
78
*-linux
89
*-macos
9-
.DS_Store
10+
*.html
11+
12+
# OS specific files
13+
.DS_Store
14+
Thumbs.db
15+
desktop.ini
16+
17+
# IDE and editor files
18+
.idea/
19+
*.swp
20+
*.swo
21+
*~
22+
23+
# Build and distribution files
24+
dist/
25+
build/
26+
27+
# Logs
28+
*.log
29+
30+
# Generated files
31+
web/js/*.min.js
32+
web/css/*.min.css

.goreleaser.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ builds:
55
- linux
66
goarch:
77
- amd64
8+
- arm64
89
archives:
910
- id: default
1011
name_template: >-
@@ -13,6 +14,7 @@ archives:
1314
{{- if eq .Os "darwin" }}macos_
1415
{{- else }}{{ .Os }}_{{ end }}
1516
{{- if eq .Arch "amd64" }}64-bit
17+
{{- else if eq .Arch "arm64" }}arm64
1618
{{- else if eq .Arch "386" }}i386
1719
{{- else if eq .Arch "darwin" }}apple
1820
{{- else }}{{ .Arch }}{{ end }}
@@ -23,6 +25,5 @@ archives:
2325
files:
2426
- NOTICE*
2527
- LICENSE*
26-
- LICENCE*
2728
- README*
2829
- CHANGELOG*

.vscode/settings.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
{
22
"cSpell.words": [
3+
"bubbletea",
4+
"charmbracelet",
35
"deepcode",
46
"goarch",
57
"gohtml",
68
"goreleaser",
79
"hasher",
810
"jacobtomlinson",
11+
"keypress",
912
"ldflags",
13+
"lipgloss",
1014
"manifoldco",
1115
"obsstudio",
12-
"promptui",
1316
"sparkdemcisin",
1417
"webp"
1518
],
@@ -19,4 +22,4 @@
1922
"file:///Users/jared/personal/github/obs-random-videos/.github/workflows/stale.yml"
2023
]
2124
}
22-
}
25+
}

LICENSE

Lines changed: 661 additions & 201 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,42 @@ Notice: the VLC Source now supports "Shuffle playlist" option.
3636
- m4v
3737
- webm
3838
- mpeg4
39+
- mov
3940

4041
#### Audio
4142

4243
- mp3
4344
- ogg
4445
- aac
4546

47+
## Project Structure
48+
49+
The project is organized into the following directories:
50+
51+
- `internal/` - Internal packages not meant for external use
52+
- `media/` - Media file handling functions (file detection, path handling)
53+
- `ui/` - User interface and template functions (prompts, HTML generation)
54+
- `web/` - Web assets
55+
- `js/` - JavaScript files for the HTML player
56+
- `main.js` - Contains the VideoPlayerManager and PlaylistManager classes
57+
- `body.js` - Initializes the player
58+
- `templates/` - HTML templates
59+
60+
### JavaScript Architecture
61+
62+
The JavaScript code uses an object-oriented approach with two main classes:
63+
64+
1. **VideoPlayerManager**: Handles the dual-player system for seamless video playback
65+
- Manages the two video players
66+
- Handles transitions between videos
67+
- Provides error handling
68+
- Implements preloading for better performance
69+
70+
2. **PlaylistManager**: Manages the playlist state and operations
71+
- Handles shuffling of videos
72+
- Manages localStorage for persistence
73+
- Provides methods for getting the next video
74+
4675
## Notes
4776

4877
- VLC Source now supports "Shuffle playlist"
@@ -54,24 +83,33 @@ Notice: the VLC Source now supports "Shuffle playlist" option.
5483
- To test in your browser you must hit the Play button first
5584
- Pro tip: webm videos support transparency (convert mov to webm to save on file size)
5685

57-
## Stuck? Or nothing happening?
86+
## Troubleshooting
87+
88+
If you're experiencing issues with the player:
5889

59-
1. Try hitting `Refresh cache of current page` in OBS
60-
2. **In OBS go to `Scene Collection` then `New`**
61-
1. **Add only your random video browser source and see if this works**
62-
2. **If it works, then theres an external issue.** I have no idea what is causing this so, if you have any info on this us know in the [discussions](https://github.com/UpDownLeftDie/obs-random-videos/discussions)
63-
3. [Enable remote debugging](https://github.com/crowbartools/Firebot/wiki/Troubleshooting-Firebot-Overlay-issues-in-OBS-Studio) and open the page for the browser source
64-
1. Open Chrome Dev tools
65-
2. `Application` tab
66-
3. Make sure `Local and session storage` box is CHECKED
67-
4. Click `Clear site data`
68-
4. If issues persist: use [GitHub Discussions](https://github.com/UpDownLeftDie/obs-random-videos/discussions/categories/q-a) or join the [Discord server](https://discord.gg/zxYsjpxaxN)
90+
1. Try hitting `Refresh cache of current page` in OBS
91+
2. **In OBS go to `Scene Collection` then `New`**
92+
1. **Add only your random video browser source and see if this works**
93+
2. **If it works, then theres an external issue.** I have no idea what is causing this so, if you have any info on this us know in the [discussions](https://github.com/UpDownLeftDie/obs-random-videos/discussions)
94+
3. [Enable remote debugging](https://github.com/crowbartools/Firebot/wiki/Troubleshooting-Firebot-Overlay-issues-in-OBS-Studio) and open the page for the browser source
95+
1. Open Chrome Dev tools
96+
2. `Application` tab
97+
3. Make sure `Local and session storage` box is CHECKED
98+
4. Click `Clear site data`
99+
4. Check if your video files are in a supported format and can be played in a browser
100+
5. Ensure your video files don't have special characters in their filenames
101+
6. If issues persist: use [GitHub Discussions](https://github.com/UpDownLeftDie/obs-random-videos/discussions/categories/q-a) or join the [Discord server](https://discord.gg/zxYsjpxaxN)
69102

70103
## TODO
71104

72-
- Audio-only or video-only modes
73-
- Option for cross-fading between videos
74-
- Option to HTML background color
105+
- [x] Support for multiple video formats
106+
- [x] Support for audio files
107+
- [x] Switch to [Bubble Tea](https://github.com/charmbracelet/bubbletea)
108+
- [ ] Audio-only or video-only modes
109+
- [ ] Option for cross-fading between videos
110+
- [ ] Option to set HTML background color
75111
- Good for videos with weird aspect ratio
76112
- Good for audio files
77-
- Switch to [Bubble Tea](https://github.com/charmbracelet/bubbletea) instead of `promptui`
113+
- [ ] Switch to [Wails](https://wails.io/) UI for a graphical interface
114+
- [ ] Add support for image files (with configurable display duration)
115+
- [ ] Improve error handling and user feedback

go.mod

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,32 @@
11
module github.com/UpDownLeftDie/obs-random-videos/v2
22

3-
go 1.21.2
3+
go 1.24.1
44

5-
require github.com/1lann/promptui v0.8.1-0.20220708222609-81fad96dd5e1
5+
require (
6+
github.com/charmbracelet/bubbles v0.21.0
7+
github.com/charmbracelet/bubbletea v1.3.5
8+
github.com/charmbracelet/lipgloss v1.1.0
9+
)
610

711
require (
8-
github.com/chzyer/readline v1.5.1 // indirect
9-
golang.org/x/sys v0.13.0 // indirect
12+
github.com/atotto/clipboard v0.1.4 // indirect
13+
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
14+
github.com/charmbracelet/colorprofile v0.3.1 // indirect
15+
github.com/charmbracelet/x/ansi v0.9.2 // indirect
16+
github.com/charmbracelet/x/cellbuf v0.0.13 // indirect
17+
github.com/charmbracelet/x/term v0.2.1 // indirect
18+
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
19+
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
20+
github.com/mattn/go-isatty v0.0.20 // indirect
21+
github.com/mattn/go-localereader v0.0.1 // indirect
22+
github.com/mattn/go-runewidth v0.0.16 // indirect
23+
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
24+
github.com/muesli/cancelreader v0.2.2 // indirect
25+
github.com/muesli/termenv v0.16.0 // indirect
26+
github.com/rivo/uniseg v0.4.7 // indirect
27+
github.com/sahilm/fuzzy v0.1.1 // indirect
28+
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
29+
golang.org/x/sync v0.15.0 // indirect
30+
golang.org/x/sys v0.33.0 // indirect
31+
golang.org/x/text v0.26.0 // indirect
1032
)

go.sum

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,57 @@
1-
github.com/1lann/promptui v0.8.1-0.20220708222609-81fad96dd5e1 h1:LejjvYg4tCW5HO7q/1nzPrprh47oUD9OUySQ29pDp5c=
2-
github.com/1lann/promptui v0.8.1-0.20220708222609-81fad96dd5e1/go.mod h1:cnC/60IoLiDM0GhdKYJ6oO7AwpZe1IQfPnSKlAURgHw=
3-
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
4-
github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM=
5-
github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
6-
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
7-
github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
8-
github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
9-
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
10-
github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04=
11-
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
12-
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
13-
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
14-
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
15-
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
1+
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
2+
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
3+
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
4+
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
5+
github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
6+
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
7+
github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs=
8+
github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg=
9+
github.com/charmbracelet/bubbletea v1.3.5 h1:JAMNLTbqMOhSwoELIr0qyP4VidFq72/6E9j7HHmRKQc=
10+
github.com/charmbracelet/bubbletea v1.3.5/go.mod h1:TkCnmH+aBd4LrXhXcqrKiYwRs7qyQx5rBgH5fVY3v54=
11+
github.com/charmbracelet/colorprofile v0.3.1 h1:k8dTHMd7fgw4bnFd7jXTLZrSU/CQrKnL3m+AxCzDz40=
12+
github.com/charmbracelet/colorprofile v0.3.1/go.mod h1:/GkGusxNs8VB/RSOh3fu0TJmQ4ICMMPApIIVn0KszZ0=
13+
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
14+
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
15+
github.com/charmbracelet/x/ansi v0.9.2 h1:92AGsQmNTRMzuzHEYfCdjQeUzTrgE1vfO5/7fEVoXdY=
16+
github.com/charmbracelet/x/ansi v0.9.2/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
17+
github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ/IA3iR28k=
18+
github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
19+
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ=
20+
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
21+
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
22+
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
23+
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
24+
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
25+
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
26+
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
27+
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
28+
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
29+
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
30+
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
31+
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
32+
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
33+
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
34+
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
35+
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
36+
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
37+
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
38+
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
39+
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
40+
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
41+
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
42+
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
43+
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
44+
github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA=
45+
github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
46+
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
47+
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
48+
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
49+
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
50+
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
51+
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
52+
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
53+
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
54+
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
55+
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
56+
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
57+
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=

internal/media/files.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package media
2+
3+
import (
4+
"fmt"
5+
"io/fs"
6+
"os"
7+
"path/filepath"
8+
"strings"
9+
)
10+
11+
// FileTypes contains the supported file extensions
12+
type FileTypes struct {
13+
Audio []string
14+
Video []string
15+
}
16+
17+
// DefaultFileTypes returns the default supported file types
18+
func DefaultFileTypes() FileTypes {
19+
return FileTypes{
20+
Audio: []string{".mp3", ".ogg", ".aac"},
21+
Video: []string{".mp4", ".webm", ".mpeg4", ".m4v", ".mov"},
22+
}
23+
}
24+
25+
// GetMediaFiles returns a list of media files in the given directory
26+
func GetMediaFiles(currentDir string, fileTypes FileTypes) []string {
27+
mediaFiles := []string{}
28+
problematicFiles := []string{}
29+
allTypes := append(fileTypes.Audio, fileTypes.Video...)
30+
31+
filepath.WalkDir(currentDir, func(path string, file fs.DirEntry, err error) error {
32+
if err != nil {
33+
return err
34+
}
35+
if !file.IsDir() && IsValidFileType(file, allTypes) {
36+
fixedFilePath := FixFilePath(path)
37+
38+
// Check for problematic characters that cause issues with file:// URLs
39+
if HasProblematicChars(file.Name()) {
40+
problematicFiles = append(problematicFiles, file.Name())
41+
}
42+
43+
mediaFiles = append(mediaFiles, fixedFilePath)
44+
}
45+
return nil
46+
})
47+
48+
// Warn about problematic files
49+
if len(problematicFiles) > 0 {
50+
fmt.Printf("\n⚠️ WARNING: Found files with characters that may cause playback issues:\n")
51+
for _, fileName := range problematicFiles {
52+
fmt.Printf(" • %s\n", fileName)
53+
}
54+
fmt.Printf("\nProblematic characters: # ; ? : @ & = + $ ,\n")
55+
fmt.Printf("Consider renaming these files to avoid potential issues.\n\n")
56+
}
57+
58+
return mediaFiles
59+
}
60+
61+
// IsValidFileType checks if a file has a supported extension
62+
func IsValidFileType(file fs.DirEntry, fileExts []string) bool {
63+
for _, ext := range fileExts {
64+
if strings.HasSuffix(file.Name(), ext) {
65+
return true
66+
}
67+
}
68+
return false
69+
}
70+
71+
// FixFilePath converts file path separators to forward slashes for HTML
72+
func FixFilePath(filePath string) string {
73+
// Only do replacement if needed (Windows paths)
74+
if os.PathSeparator != '/' {
75+
return strings.ReplaceAll(filePath, string(os.PathSeparator), "/")
76+
}
77+
return filePath
78+
}
79+
80+
// HasProblematicChars checks if a filename contains characters that cause issues with file:// URLs
81+
func HasProblematicChars(fileName string) bool {
82+
problematicChars := []string{"#", ";", "?", ":", "@", "&", "=", "+", "$", ","}
83+
for _, char := range problematicChars {
84+
if strings.Contains(fileName, char) {
85+
return true
86+
}
87+
}
88+
return false
89+
}
90+
91+
// RemoveTransitionVideo removes the transition video from the list of media files
92+
func RemoveTransitionVideo(transitionVideo string, mediaFiles []string) []string {
93+
var result []string
94+
for _, file := range mediaFiles {
95+
if file != transitionVideo {
96+
result = append(result, file)
97+
}
98+
}
99+
return result
100+
}

0 commit comments

Comments
 (0)