|
1 | 1 | <!DOCTYPE html> |
2 | | -<html> |
3 | | - <head> |
4 | | - <meta charset="utf-8"> |
5 | | - <meta name="viewport" content="width=device-width, initial-scale=1"> |
| 2 | +<html lang="en"> |
| 3 | +<head> |
| 4 | + <meta charset="utf-8"> |
| 5 | + <meta name="viewport" content="width=device-width, initial-scale=1"> |
| 6 | + <title>Musicians' Helper - Repeater</title> |
6 | 7 |
|
7 | | - <title>Musicians' Helper - Repeater</title> |
| 8 | + <!-- Fonts --> |
| 9 | + <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet"> |
8 | 10 |
|
9 | | - <!-- Fonts --> |
10 | | - <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet"> |
11 | | - |
12 | | - <!-- Styles --> |
13 | | - <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> |
14 | | - <link rel="stylesheet" href="styles.css"> |
| 11 | + <!-- Styles --> |
| 12 | + <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> |
| 13 | + <link rel="stylesheet" href="styles.css"> |
| 14 | + |
| 15 | + <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> |
| 16 | + <script src="https://cdn.jsdelivr.net/npm/bs-custom-file-input/dist/bs-custom-file-input.min.js"></script> |
| 17 | + <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js" integrity="sha512-qTXRIMyZIFb8iQcfjXWCO8+M5Tbc38Qi5WzdPOYZHIlZpzBHG3L3by84BBBOiRGiEb7KKtAOAs5qYdUiZiQNNQ==" crossorigin="anonymous"></script> |
| 18 | +</head> |
| 19 | +<body> |
| 20 | + <div class="container-fluid"> |
| 21 | + <div class="text-center py-5"> |
| 22 | + <h2>Musicians' Helper - Repeater</h2> |
| 23 | + <h3>A tool used by musicians to learn new songs.</h3> |
| 24 | + <p> |
| 25 | + Insert a YouTube video URL below and, by default, the loop |
| 26 | + will start at 0 seconds and restart at the end of the video. |
| 27 | + <br> |
| 28 | + Configure the loop start and end points to repeat specific parts of the song, saving time identifying notes and chords. |
| 29 | + </p> |
| 30 | + </div> |
15 | 31 |
|
16 | | - <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> |
17 | | - <script src="https://cdn.jsdelivr.net/npm/bs-custom-file-input/dist/bs-custom-file-input.min.js"></script> |
18 | | - <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js" integrity="sha512-qTXRIMyZIFb8iQcfjXWCO8+M5Tbc38Qi5WzdPOYZHIlZpzBHG3L3by84BBBOiRGiEb7KKtAOAs5qYdUiZiQNNQ==" crossorigin="anonymous"></script> |
19 | | - </head> |
20 | | - <body> |
21 | | - <div class="container-fluid"> |
22 | | - <div class="text-center py-5"> |
23 | | - <h2>Musicians' Helper - Repeater</h2> |
24 | | - <h3>A tool used by musicians to learn new songs.</h3> |
25 | | - |
26 | | - <p> |
27 | | - Insert an Youtube video URL below and, by default, the loop |
28 | | - will start at 0 seconds and restart at the end of the video. |
29 | | - |
30 | | - <br> |
31 | | - |
32 | | - You can change this values to configure which part of the song you want to repeat automatically. |
33 | | - It saves a lot of time to find which note/chord you're hearing. |
34 | | - </p> |
35 | | - </div> |
36 | | - |
37 | | - <div class="row"> |
38 | | - <div class="col-6"> |
39 | | - <form> |
40 | | - <div class="form-group row"> |
41 | | - <label class="col-4 col-form-label" for="video_url">Video URL</label> |
42 | | - <input id="video-url" class="col-8 form-control" name="video_url" type="text" value="" placeholder="https://www.youtube.com/watch?v=WqQKw8m-C2k"> |
43 | | - <div id="url-invalid" class="offset-4 col-8 invalid-feedback"> |
44 | | - Invalid URL. Please, insert a Youtube video URL according to this format: https://www.youtube.com/watch?v={video_id} |
| 32 | + <div class="row"> |
| 33 | + <!-- Video URL and Controls Column --> |
| 34 | + <div class="col-md-6 col-sm-12 mb-4"> |
| 35 | + <form> |
| 36 | + <div class="form-group row"> |
| 37 | + <label class="col-md-4 col-form-label" for="video_url">Video URL</label> |
| 38 | + <div class="col-md-8 col-sm-12"> |
| 39 | + <input id="video-url" class="form-control" name="video_url" type="text" placeholder="https://www.youtube.com/watch?v=WqQKw8m-C2k"> |
| 40 | + <div id="url-invalid" class="invalid-feedback"> |
| 41 | + Invalid URL. Please insert a valid YouTube video URL (https://www.youtube.com/watch?v={video_id}). |
45 | 42 | </div> |
46 | 43 | </div> |
47 | | - <div class="form-group row"> |
| 44 | + </div> |
| 45 | + |
| 46 | + <!-- Loop Start Control --> |
| 47 | + <div class="form-group row"> |
| 48 | + <label class="col-md-4 col-form-label" for="start">Start <span class="text-muted">(seconds)</span></label> |
| 49 | + <div class="col-md-8"> |
48 | 50 | <div class="input-group"> |
49 | | - <label class="col-4 col-form-label" for="start">Start <span class="text-muted">(seconds)</span></label> |
50 | 51 | <div class="input-group-prepend"> |
51 | 52 | <button class="btn btn-outline-secondary subtract" data-amount="10" type="button">-10 s</button> |
52 | 53 | <button class="btn btn-outline-secondary subtract" data-amount="1" type="button">-1 s</button> |
53 | 54 | <button class="btn btn-outline-secondary subtract" data-amount="0.1" type="button">-100 ms</button> |
54 | 55 | </div> |
55 | | - <input id="start" class="col-4 form-control" name="start" type="number" min="0" value="" step=".1" placeholder="16,2"> |
| 56 | + <input id="start" class="form-control" name="start" type="number" min="0" step=".1" placeholder="16.2"> |
56 | 57 | <div class="input-group-append"> |
57 | 58 | <button class="btn btn-outline-secondary sum" data-amount="0.1" type="button">+100 ms</button> |
58 | 59 | <button class="btn btn-outline-secondary sum" data-amount="1" type="button">+1 s</button> |
59 | 60 | <button class="btn btn-outline-secondary sum" data-amount="10" type="button">+10 s</button> |
60 | 61 | </div> |
61 | 62 | </div> |
62 | 63 | </div> |
63 | | - <div class="form-group row"> |
| 64 | + </div> |
| 65 | + |
| 66 | + <!-- Loop Duration Control --> |
| 67 | + <div class="form-group row"> |
| 68 | + <label class="col-md-4 col-form-label" for="duration">Duration <span class="text-muted">(seconds)</span></label> |
| 69 | + <div class="col-md-8"> |
64 | 70 | <div class="input-group"> |
65 | | - <label class="col-4 col-form-label" for="duration">Duration <span class="text-muted">(seconds)</span></label> |
66 | 71 | <div class="input-group-prepend"> |
67 | 72 | <button class="btn btn-outline-secondary subtract" data-amount="10" type="button">-10 s</button> |
68 | 73 | <button class="btn btn-outline-secondary subtract" data-amount="1" type="button">-1 s</button> |
69 | 74 | <button class="btn btn-outline-secondary subtract" data-amount="0.1" type="button">-100 ms</button> |
70 | 75 | </div> |
71 | | - <input id="duration" class="col-6 form-control" name="duration" type="number" min="0" value="" step=".1" placeholder="42,8"> |
| 76 | + <input id="duration" class="form-control" name="duration" type="number" min="0" step=".1" placeholder="42.8"> |
72 | 77 | <div class="input-group-append"> |
73 | 78 | <button class="btn btn-outline-secondary sum" data-amount="0.1" type="button">+100 ms</button> |
74 | 79 | <button class="btn btn-outline-secondary sum" data-amount="1" type="button">+1 s</button> |
75 | 80 | <button class="btn btn-outline-secondary sum" data-amount="10" type="button">+10 s</button> |
76 | 81 | </div> |
77 | 82 | </div> |
78 | 83 | </div> |
79 | | - <div class="form-group row"> |
| 84 | + </div> |
| 85 | + |
| 86 | + <!-- Loop End Control --> |
| 87 | + <div class="form-group row"> |
| 88 | + <label class="col-md-4 col-form-label" for="end">End <span class="text-muted">(seconds)</span></label> |
| 89 | + <div class="col-md-8"> |
80 | 90 | <div class="input-group"> |
81 | | - <label class="col-4 col-form-label" for="end">End <span class="text-muted">(seconds)</span></label> |
82 | 91 | <div class="input-group-prepend"> |
83 | 92 | <button class="btn btn-outline-secondary subtract" data-amount="10" type="button">-10 s</button> |
84 | 93 | <button class="btn btn-outline-secondary subtract" data-amount="1" type="button">-1 s</button> |
85 | 94 | <button class="btn btn-outline-secondary subtract" data-amount="0.1" type="button">-100 ms</button> |
86 | 95 | </div> |
87 | | - <input id="end" class="col-4 form-control" name="end" type="number" min="0" value="" step=".1" placeholder="16,2"> |
| 96 | + <input id="end" class="form-control" name="end" type="number" min="0" step=".1" placeholder="42.8"> |
88 | 97 | <div class="input-group-append"> |
89 | 98 | <button class="btn btn-outline-secondary sum" data-amount="0.1" type="button">+100 ms</button> |
90 | 99 | <button class="btn btn-outline-secondary sum" data-amount="1" type="button">+1 s</button> |
91 | 100 | <button class="btn btn-outline-secondary sum" data-amount="10" type="button">+10 s</button> |
92 | 101 | </div> |
93 | 102 | </div> |
94 | 103 | </div> |
95 | | - <div class="form-group row"> |
96 | | - <div class="col-4"> |
97 | | - <label class="col-form-label">Chords File <span class="text-muted">(.srt)</span></label> |
98 | | - </div> |
99 | | - <div class="col-8 custom-file"> |
100 | | - <label class="custom-file-label" for="chords_file">Choose File</label> |
101 | | - <input type="file" class="custom-file-input" id="chords-file" /> |
102 | | - </div> |
103 | | - </div> |
104 | | - </form> |
| 104 | + </div> |
105 | 105 |
|
106 | | - <div id="chords"></div> |
107 | | - </div> |
108 | | - <div class="col-6"> |
109 | | - <div id="player-wrapper" class="text-center" style="position:sticky;top:20px;"> |
110 | | - <!-- 1. The <iframe> (and video player) will replace this <div> tag. --> |
111 | | - <div id="player" style="display:none"></div> |
| 106 | + <!-- Chords File Upload --> |
| 107 | + <div class="form-group row"> |
| 108 | + <label class="col-md-4 col-form-label">Chords File <span class="text-muted">(.srt)</span></label> |
| 109 | + <div class="col-md-8 custom-file"> |
| 110 | + <input type="file" class="custom-file-input" id="chords-file"> |
| 111 | + <label class="custom-file-label" for="chords_file">Choose File</label> |
| 112 | + </div> |
112 | 113 | </div> |
| 114 | + </form> |
| 115 | + |
| 116 | + <div id="chords"></div> |
| 117 | + </div> |
| 118 | + |
| 119 | + <!-- Video Player Column --> |
| 120 | + <div class="col-md-6 col-sm-12 text-center"> |
| 121 | + <div id="player-wrapper" class="sticky-top"> |
| 122 | + <div id="player" style="display:none"></div> |
113 | 123 | </div> |
114 | 124 | </div> |
115 | 125 | </div> |
| 126 | + </div> |
116 | 127 |
|
117 | | - <script src="scripts.js"></script> |
118 | | - </body> |
| 128 | + <script src="scripts.js"></script> |
| 129 | +</body> |
119 | 130 | </html> |
0 commit comments