Skip to content

Commit b7c3856

Browse files
authored
Show iPhone suggested ffmpg commands too
https://chatgpt.com/share/687018f5-2360-8006-aa2c-50f6235a3101 o3 also changed to backtick strings in a few places.
1 parent 4fd16bc commit b7c3856

File tree

1 file changed

+31
-24
lines changed

1 file changed

+31
-24
lines changed

ffmpeg-crop.html

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
word-break: break-all;
129129
user-select: all;
130130
cursor: text;
131+
margin-bottom: 20px;
131132
}
132133

133134
.info {
@@ -167,10 +168,12 @@ <h1>FFmpeg video crop</h1>
167168
<div class="command-container hidden" id="commandContainer">
168169
<div class="command-label">FFmpeg command:</div>
169170
<div class="command" id="ffmpegCommand"></div>
171+
<div class="command-label">Recommended settings for iPhone compatibility:</div>
172+
<div class="command" id="ffmpegCommandIOS"></div>
170173
</div>
171174

172175
<div class="info">
173-
Upload a video file, then drag the green crop box to select the area you want to keep. The ffmpeg command will update automatically as you adjust the crop area.
176+
Upload a video file, then drag the green crop box to select the area you want to keep. The ffmpeg commands will update automatically as you adjust the crop area.
174177
</div>
175178

176179
<script type="module">
@@ -182,6 +185,7 @@ <h1>FFmpeg video crop</h1>
182185
const cropDimensions = document.getElementById('cropDimensions');
183186
const commandContainer = document.getElementById('commandContainer');
184187
const ffmpegCommand = document.getElementById('ffmpegCommand');
188+
const ffmpegCommandIOS = document.getElementById('ffmpegCommandIOS');
185189

186190
let videoWidth = 0;
187191
let videoHeight = 0;
@@ -198,23 +202,22 @@ <h1>FFmpeg video crop</h1>
198202
// Initialize crop box position and size
199203
function initializeCropBox() {
200204
const rect = video.getBoundingClientRect();
201-
const overlayRect = cropOverlay.getBoundingClientRect();
202205

203206
// Set initial crop box to 50% of video size, centered
204207
const initialWidth = rect.width * 0.5;
205208
const initialHeight = rect.height * 0.5;
206209
const initialLeft = (rect.width - initialWidth) / 2;
207210
const initialTop = (rect.height - initialHeight) / 2;
208211

209-
cropBox.style.left = initialLeft + 'px';
210-
cropBox.style.top = initialTop + 'px';
211-
cropBox.style.width = initialWidth + 'px';
212-
cropBox.style.height = initialHeight + 'px';
212+
cropBox.style.left = `${initialLeft}px`;
213+
cropBox.style.top = `${initialTop}px`;
214+
cropBox.style.width = `${initialWidth}px`;
215+
cropBox.style.height = `${initialHeight}px`;
213216

214217
updateCommand();
215218
}
216219

217-
// Update ffmpeg command based on crop box
220+
// Update ffmpeg commands based on crop box
218221
function updateCommand() {
219222
const rect = video.getBoundingClientRect();
220223
const boxRect = cropBox.getBoundingClientRect();
@@ -232,11 +235,17 @@ <h1>FFmpeg video crop</h1>
232235
// Update dimensions display
233236
cropDimensions.textContent = `${cropW} × ${cropH}`;
234237

235-
// Update ffmpeg command
238+
// Build file names
236239
const inputFile = videoInput.files[0] ? videoInput.files[0].name : 'input.mp4';
237-
const outputFile = inputFile.replace(/\.[^/.]+$/, '') + '_cropped.mp4';
240+
const baseName = inputFile.replace(/\.[^/.]+$/, '');
241+
const outputFile = `${baseName}_cropped.mp4`;
242+
const outputFileIOS = `${baseName}_cropped_ios.mp4`;
238243

244+
// Standard command
239245
ffmpegCommand.textContent = `ffmpeg -i "${inputFile}" -vf "crop=${cropW}:${cropH}:${cropX}:${cropY}" -c:a copy "${outputFile}"`;
246+
247+
// iPhone‑friendly command
248+
ffmpegCommandIOS.textContent = `ffmpeg -i "${inputFile}" -vf "crop=${cropW}:${cropH}:${cropX}:${cropY}" -c:v libx264 -profile:v main -level 3.1 -pix_fmt yuv420p -c:a copy "${outputFileIOS}"`;
240249
}
241250

242251
// Handle video file selection
@@ -254,10 +263,8 @@ <h1>FFmpeg video crop</h1>
254263
commandContainer.classList.remove('hidden');
255264

256265
// Wait for next frame to ensure video is rendered
257-
requestAnimationFrame(() => {
258-
initializeCropBox();
259-
});
260-
});
266+
requestAnimationFrame(initializeCropBox);
267+
}, { once: true });
261268
}
262269
});
263270

@@ -310,8 +317,8 @@ <h1>FFmpeg video crop</h1>
310317
newLeft = Math.max(0, Math.min(newLeft, maxLeft));
311318
newTop = Math.max(0, Math.min(newTop, maxTop));
312319

313-
cropBox.style.left = newLeft + 'px';
314-
cropBox.style.top = newTop + 'px';
320+
cropBox.style.left = `${newLeft}px`;
321+
cropBox.style.top = `${newTop}px`;
315322

316323
updateCommand();
317324
}
@@ -346,15 +353,15 @@ <h1>FFmpeg video crop</h1>
346353
// Minimum size constraints
347354
if (newWidth >= 50 && newHeight >= 50) {
348355
// Constrain to video bounds
349-
if (newLeft >= 0 && newTop >= 0 &&
350-
newLeft + newWidth <= cropOverlay.offsetWidth &&
351-
newTop + newHeight <= cropOverlay.offsetHeight) {
352-
353-
cropBox.style.left = newLeft + 'px';
354-
cropBox.style.top = newTop + 'px';
355-
cropBox.style.width = newWidth + 'px';
356-
cropBox.style.height = newHeight + 'px';
357-
356+
if (
357+
newLeft >= 0 && newTop >= 0 &&
358+
newLeft + newWidth <= cropOverlay.offsetWidth &&
359+
newTop + newHeight <= cropOverlay.offsetHeight
360+
) {
361+
cropBox.style.left = `${newLeft}px`;
362+
cropBox.style.top = `${newTop}px`;
363+
cropBox.style.width = `${newWidth}px`;
364+
cropBox.style.height = `${newHeight}px`;
358365
updateCommand();
359366
}
360367
}

0 commit comments

Comments
 (0)