diff --git a/src/components/downloadOptionsDialog/downloadOptionsDialog.js b/src/components/downloadOptionsDialog/downloadOptionsDialog.js
new file mode 100644
index 0000000000..a240907c1f
--- /dev/null
+++ b/src/components/downloadOptionsDialog/downloadOptionsDialog.js
@@ -0,0 +1,576 @@
+import dialogHelper from '../dialogHelper/dialogHelper';
+import layoutManager from '../layoutManager';
+import globalize from '../../lib/globalize';
+import loading from '../loading/loading';
+import toast from '../toast/toast';
+import { getVideoQualityOptions } from '../qualityOptions';
+import template from './downloadOptionsDialog.template.html';
+import '../../elements/emby-select/emby-select';
+import '../../elements/emby-button/emby-button';
+import './downloadOptionsDialog.scss';
+
+let currentItem;
+let currentApiClient;
+
+function getBitrateOptionsForResolutionAndCodec(resolution, codec) {
+    // Codec efficiency factors (Jellyfin defaults)
+    const codecFactors = {
+        'h264': 1.0,
+        'hevc': 0.6,   // 40% more efficient
+        'vp9': 0.6,    // 40% more efficient
+        'av1': 0.5     // 50% more efficient
+    };
+
+    // Base bitrate ranges for H.264 (updated for 2025 standards)
+    const baseRanges = {
+        '3840': { min: 25000000, max: 80000000, label: '4K' },      // 25-80 Mbps
+        '2560': { min: 12000000, max: 35000000, label: '1440p' },   // 12-35 Mbps
+        '1920': { min: 5000000, max: 16000000, label: '1080p' },    // 5-16 Mbps
+        '1280': { min: 2500000, max: 8000000, label: '720p' },      // 2.5-8 Mbps
+        '640': { min: 1000000, max: 2500000, label: '480p' },       // 1-2.5 Mbps
+        'original': { min: 50000000, max: 120000000, label: 'Original' }
+    };
+
+    if (resolution === 'original') {
+        return [
+            { bitrate: 120000000, name: 'Extreme Quality' },
+            { bitrate: 100000000, name: 'Maximum' },
+            { bitrate: 80000000, name: 'High' },
+            { bitrate: 60000000, name: 'Medium' },
+            { bitrate: 50000000, name: 'Standard' }
+        ];
+    }
+
+    const range = baseRanges[resolution] || baseRanges['1920'];
+    const factor = codecFactors[codec] || 1.0;
+
+    const min = Math.round(range.min * factor);
+    const max = Math.round(range.max * factor);
+    const step = (max - min) / 5;
+
+    // Generate 6 quality levels
+    return [
+        { bitrate: max, name: `Maximum (${range.label})` },
+        { bitrate: Math.round(max - step), name: `Very High (${range.label})` },
+        { bitrate: Math.round(max - step * 2), name: `High (${range.label})` },
+        { bitrate: Math.round(max - step * 3), name: `Medium (${range.label})` },
+        { bitrate: Math.round(max - step * 4), name: `Low (${range.label})` },
+        { bitrate: min, name: `Minimum (${range.label})` }
+    ];
+}
+
+function populateQualityOptions(dlg, item) {
+    const selectQuality = dlg.querySelector('#selectQuality');
+    const selectResolution = dlg.querySelector('#selectResolution');
+    const selectVideoCodec = dlg.querySelector('#selectVideoCodec');
+
+    const resolution = selectResolution?.value || '1920';
+    const codec = selectVideoCodec?.value || 'h264';
+
+    if (codec === 'copy') {
+        selectQuality.innerHTML = '<option value="0">Original Quality</option>';
+        return;
+    }
+
+    const options = getBitrateOptionsForResolutionAndCodec(resolution, codec);
+
+    selectQuality.innerHTML = options.map((option, index) => {
+        const selected = index === 2 ? ' selected' : ''; // Select "High" (3rd option)
+        const mbps = (option.bitrate / 1000000).toFixed(1);
+        return `<option value="${option.bitrate}"${selected}>${option.name} - ${mbps} Mbps</option>`;
+    }).join('');
+}
+
+function populateAudioTracks(dlg, item) {
+    const selectAudioTrack = dlg.querySelector('#selectAudioTrack');
+    const audioStreams = item.MediaSources?.[0]?.MediaStreams?.filter(s => s.Type === 'Audio') || [];
+
+    selectAudioTrack.innerHTML = audioStreams.map((stream, index) => {
+        const language = stream.Language || 'Unknown';
+        const codec = stream.Codec ? stream.Codec.toUpperCase() : '';
+        const channels = stream.Channels ? `${stream.Channels}.0` : '';
+        const displayTitle = stream.DisplayTitle || `Track ${index + 1}`;
+        const selected = stream.IsDefault ? ' selected' : '';
+
+        return `<option value="${stream.Index}" data-channels="${stream.Channels || 2}"${selected}>${displayTitle}</option>`;
+    }).join('');
+
+    if (audioStreams.length === 0) {
+        selectAudioTrack.innerHTML = '<option value="-1" data-channels="2">No Audio</option>';
+    }
+}
+
+function getRecommendedAudioBitrate(codec, channels) {
+    // Recommended bitrates based on codec and channel count (2025 standards)
+    const bitrates = {
+        'aac': {
+            2: 192000,   // Stereo - transparent quality
+            6: 256000,   // 5.1 - Netflix/streaming standard
+            8: 384000    // 7.1 - high quality
+        },
+        'ac3': {
+            2: 192000,   // Stereo
+            6: 448000,   // 5.1 - Dolby Digital standard (fixed at 448k)
+            8: 640000    // 7.1 - Dolby Digital spec maximum
+        },
+        'eac3': {
+            2: 224000,   // Stereo - DD+ improved quality
+            6: 384000,   // 5.1 - DD+ standard
+            8: 768000    // 7.1 - DD+ maximum
+        },
+        'opus': {
+            2: 128000,   // Stereo - excellent quality (Opus is very efficient)
+            6: 256000,   // 5.1 - high quality
+            8: 384000    // 7.1 - very high quality
+        },
+        'mp3': {
+            2: 192000,   // Stereo - "very high quality" (320k is overkill)
+            6: 192000,   // Downmix to stereo (MP3 doesn't support multichannel)
+            8: 192000    // Downmix to stereo
+        }
+    };
+
+    return bitrates[codec]?.[channels] || bitrates[codec]?.[2] || 192000;
+}
+
+function getMaxAudioBitrate(codec) {
+    // Maximum sensible bitrates per codec
+    const maxBitrates = {
+        'aac': 512000,      // AAC practical max for 7.1
+        'ac3': 640000,      // AC3 spec maximum
+        'eac3': 1536000,    // E-AC3 spec maximum (Atmos capable)
+        'opus': 510000,     // Opus practical max (very efficient)
+        'mp3': 320000       // MP3 spec maximum
+    };
+
+    return maxBitrates[codec] || 640000;
+}
+
+function updateAudioBitrateOptions(dlg) {
+    const selectAudioCodec = dlg.querySelector('#selectAudioCodec');
+    const selectAudioTrack = dlg.querySelector('#selectAudioTrack');
+    const selectAudioBitrate = dlg.querySelector('#selectAudioBitrate');
+    const audioBitrateContainer = dlg.querySelector('#selectAudioBitrate').closest('.selectContainer');
+
+    const codec = selectAudioCodec.value;
+    const selectedTrack = selectAudioTrack.options[selectAudioTrack.selectedIndex];
+    const channels = parseInt(selectedTrack?.getAttribute('data-channels') || '2');
+
+    // Hide bitrate selector for "copy"
+    if (codec === 'copy') {
+        audioBitrateContainer.style.display = 'none';
+        return;
+    } else {
+        audioBitrateContainer.style.display = 'block';
+    }
+
+    const maxBitrate = getMaxAudioBitrate(codec);
+    const recommendedBitrate = getRecommendedAudioBitrate(codec, channels);
+
+    // Filter and update bitrate options based on codec
+    const options = selectAudioBitrate.querySelectorAll('option');
+    let needsReset = false;
+    const currentBitrate = parseInt(selectAudioBitrate.value);
+
+    options.forEach(option => {
+        const bitrate = parseInt(option.value);
+        const text = option.textContent.replace(' (Recommended)', '');
+
+        // Hide options exceeding codec maximum
+        if (bitrate > maxBitrate) {
+            option.style.display = 'none';
+            option.disabled = true;
+            if (bitrate === currentBitrate) {
+                needsReset = true;
+            }
+        } else {
+            option.style.display = '';
+            option.disabled = false;
+        }
+
+        // Mark recommended bitrate
+        if (bitrate === recommendedBitrate && bitrate <= maxBitrate) {
+            option.textContent = text + ' (Recommended)';
+            if (needsReset || currentBitrate > maxBitrate) {
+                option.selected = true;
+            }
+        } else {
+            option.textContent = text;
+        }
+    });
+
+    // If current selection exceeds max, select recommended
+    if (needsReset || currentBitrate > maxBitrate) {
+        selectAudioBitrate.value = recommendedBitrate.toString();
+    }
+}
+
+function populateSubtitles(dlg, item) {
+    const selectSubtitle = dlg.querySelector('#selectSubtitle');
+    const subtitleStreams = item.MediaSources?.[0]?.MediaStreams?.filter(s => s.Type === 'Subtitle') || [];
+
+    let options = '<option value="none" selected>None</option>';
+
+    options += subtitleStreams.map(stream => {
+        const language = stream.Language || 'Unknown';
+        const codec = stream.Codec ? stream.Codec.toUpperCase() : '';
+        const displayTitle = stream.DisplayTitle || `${language} (${codec})`;
+
+        return `<option value="${stream.Index}">${displayTitle}</option>`;
+    }).join('');
+
+    selectSubtitle.innerHTML = options;
+}
+
+function updateSubtitleMethod(dlg) {
+    const selectSubtitle = dlg.querySelector('#selectSubtitle');
+    const subtitleMethodContainer = dlg.querySelector('#subtitleMethodContainer');
+
+    if (selectSubtitle.value === 'none') {
+        subtitleMethodContainer.style.display = 'none';
+    } else {
+        subtitleMethodContainer.style.display = 'block';
+    }
+}
+
+function updateEstimatedSize(dlg, item) {
+    const selectQuality = dlg.querySelector('#selectQuality');
+    const selectAudioBitrate = dlg.querySelector('#selectAudioBitrate');
+    const selectVideoCodec = dlg.querySelector('#selectVideoCodec');
+
+    const videoBitrate = parseInt(selectQuality.value) || 0;
+    const audioBitrate = parseInt(selectAudioBitrate.value) || 0;
+    const duration = item.RunTimeTicks ? item.RunTimeTicks / 10000000 : 0; // Convert to seconds
+
+    // For "Copy Original" mode, use original file size if available
+    if (selectVideoCodec.value === 'copy') {
+        const originalSizeBytes = item.MediaSources?.[0]?.Size;
+        if (originalSizeBytes) {
+            const sizeGB = originalSizeBytes / 1024 / 1024 / 1024;
+            dlg.querySelector('#sizeValue').textContent = `~${sizeGB.toFixed(2)} GB`;
+        } else {
+            dlg.querySelector('#sizeValue').textContent = 'Unknown';
+        }
+    } else if (videoBitrate > 0 && duration > 0) {
+        // Calculate size: (video + audio bitrate) * duration / 8 / 1024 / 1024 / 1024 = GB
+        const totalBitrate = videoBitrate + audioBitrate;
+        const sizeGB = (totalBitrate * duration) / 8 / 1024 / 1024 / 1024;
+        dlg.querySelector('#sizeValue').textContent = `~${sizeGB.toFixed(2)} GB`;
+    } else {
+        dlg.querySelector('#sizeValue').textContent = 'Unknown';
+    }
+
+    // Duration
+    if (duration > 0) {
+        const hours = Math.floor(duration / 3600);
+        const minutes = Math.floor((duration % 3600) / 60);
+        dlg.querySelector('#durationValue').textContent = `${hours}h ${minutes}m`;
+    }
+}
+
+function updateCodecCompatibility(dlg) {
+    const selectVideoCodec = dlg.querySelector('#selectVideoCodec');
+    const selectAudioCodec = dlg.querySelector('#selectAudioCodec');
+    const selectContainer = dlg.querySelector('#selectContainer');
+    const resolutionContainer = dlg.querySelector('#selectResolution').closest('.selectContainer');
+    const qualityContainer = dlg.querySelector('#selectQuality').closest('.selectContainer');
+    const audioCodecContainer = dlg.querySelector('#selectAudioCodec').closest('.selectContainer');
+    const audioBitrateContainer = dlg.querySelector('#selectAudioBitrate').closest('.selectContainer');
+    const containerContainer = dlg.querySelector('#selectContainer').closest('.selectContainer');
+
+    const videoCodec = selectVideoCodec.value;
+    const container = selectContainer.value;
+    const currentAudioCodec = selectAudioCodec.value;
+
+    // If "Copy Original" is selected, hide all transcode options
+    if (videoCodec === 'copy') {
+        resolutionContainer.style.display = 'none';
+        qualityContainer.style.display = 'none';
+        audioCodecContainer.style.display = 'none';
+        audioBitrateContainer.style.display = 'none';
+        containerContainer.style.display = 'none';
+        return;
+    } else {
+        resolutionContainer.style.display = 'block';
+        qualityContainer.style.display = 'block';
+        audioCodecContainer.style.display = 'block';
+        audioBitrateContainer.style.display = 'block';
+        containerContainer.style.display = 'block';
+    }
+
+    // Filter container options based on video codec
+    const containerOptions = selectContainer.querySelectorAll('option');
+    let needsContainerReset = false;
+
+    containerOptions.forEach(option => {
+        const cont = option.value;
+        let compatible = true;
+
+        // VP9 is WebM-optimized (not compatible with MP4)
+        if (videoCodec === 'vp9' && cont === 'mp4') {
+            compatible = false;
+        }
+        // HEVC not compatible with WebM
+        if (videoCodec === 'hevc' && cont === 'webm') {
+            compatible = false;
+        }
+        // H.264 not typically used with WebM
+        if (videoCodec === 'h264' && cont === 'webm') {
+            compatible = false;
+        }
+        // AV1 and MKV support all containers
+
+        if (compatible) {
+            option.style.display = '';
+            option.disabled = false;
+        } else {
+            option.style.display = 'none';
+            option.disabled = true;
+            if (cont === container) {
+                needsContainerReset = true;
+            }
+        }
+    });
+
+    // Reset container if current selection is incompatible
+    if (needsContainerReset) {
+        if (videoCodec === 'vp9') {
+            selectContainer.value = 'webm';
+        } else if (videoCodec === 'hevc' || videoCodec === 'h264') {
+            selectContainer.value = 'mkv';
+        } else if (videoCodec === 'av1') {
+            selectContainer.value = 'mkv';
+        }
+    }
+
+    // Filter audio codec options based on container
+    const audioOptions = selectAudioCodec.querySelectorAll('option');
+    let needsAudioReset = false;
+
+    audioOptions.forEach(option => {
+        const codec = option.value;
+        let compatible = true;
+
+        if (container === 'webm') {
+            // WebM only supports Opus
+            compatible = (codec === 'opus' || codec === 'copy');
+        } else if (container === 'mp4') {
+            // MP4 doesn't support Opus
+            compatible = (codec !== 'opus');
+        }
+        // MKV supports everything
+
+        if (compatible) {
+            option.style.display = '';
+            option.disabled = false;
+        } else {
+            option.style.display = 'none';
+            option.disabled = true;
+            if (codec === currentAudioCodec) {
+                needsAudioReset = true;
+            }
+        }
+    });
+
+    // Reset audio codec if current selection is incompatible
+    if (needsAudioReset) {
+        if (container === 'webm') {
+            selectAudioCodec.value = 'opus';
+        } else if (container === 'mp4') {
+            selectAudioCodec.value = 'aac';
+        }
+    }
+}
+
+function buildDownloadUrl(apiClient, item, options) {
+    const params = new URLSearchParams({
+        videoCodec: options.videoCodec,
+        audioCodec: options.audioCodec,
+        container: options.container,
+        videoBitRate: options.videoBitRate,
+        audioBitRate: options.audioBitRate,
+        audioStreamIndex: options.audioStreamIndex,
+        playSessionId: new Date().getTime().toString()  // Unique ID to prevent caching
+    });
+
+    // Force transcoding - disable stream copy
+    // User can select "Copy Original" if they want to copy instead
+    params.set('enableAutoStreamCopy', 'false');
+    params.set('allowVideoStreamCopy', 'false');
+    params.set('allowAudioStreamCopy', 'false');
+
+    // Add resolution if not original
+    if (options.maxWidth && options.maxWidth !== 'original') {
+        params.set('maxWidth', options.maxWidth);
+        // Calculate height based on 16:9 aspect ratio
+        const maxHeight = Math.round(parseInt(options.maxWidth) * 9 / 16);
+        params.set('maxHeight', maxHeight.toString());
+    }
+
+    // Subtitles
+    if (options.subtitleStreamIndex !== null && options.subtitleStreamIndex !== 'none') {
+        params.set('subtitleStreamIndex', options.subtitleStreamIndex);
+        params.set('subtitleMethod', options.subtitleMethod);
+    }
+
+    // Ensure proper seeking and duration metadata (copyTimestamps=false uses re-encoded timestamps)
+    params.set('copyTimestamps', 'false');
+
+    const url = `${apiClient.getUrl(`/Videos/${item.Id}/stream?${params.toString()}`)}`;
+    console.log('Download URL:', url);
+    return url;
+}
+
+function onSubmit(e) {
+    e.preventDefault();
+
+    const dlg = e.target;
+    const selectResolution = dlg.querySelector('#selectResolution');
+    const selectQuality = dlg.querySelector('#selectQuality');
+    const selectVideoCodec = dlg.querySelector('#selectVideoCodec');
+    const selectAudioTrack = dlg.querySelector('#selectAudioTrack');
+    const selectAudioCodec = dlg.querySelector('#selectAudioCodec');
+    const selectAudioBitrate = dlg.querySelector('#selectAudioBitrate');
+    const selectSubtitle = dlg.querySelector('#selectSubtitle');
+    const selectSubtitleMethod = dlg.querySelector('#selectSubtitleMethod');
+    const selectContainer = dlg.querySelector('#selectContainer');
+
+    // Create download
+    import('../../scripts/fileDownloader').then((fileDownloader) => {
+        let downloadUrl;
+        let filename;
+        let title;
+
+        // Check if user wants original file
+        if (selectVideoCodec.value === 'copy') {
+            downloadUrl = currentApiClient.getItemDownloadUrl(currentItem.Id);
+            filename = currentItem.Path ? currentItem.Path.replace(/^.*[\\/]/, '') : `${currentItem.Name}.${currentItem.Container || 'mkv'}`;
+            title = `${currentItem.Name} (Original)`;
+        } else {
+            const options = {
+                maxWidth: selectResolution.value,
+                videoBitRate: parseInt(selectQuality.value),
+                videoCodec: selectVideoCodec.value,
+                audioStreamIndex: parseInt(selectAudioTrack.value),
+                audioCodec: selectAudioCodec.value,
+                audioBitRate: parseInt(selectAudioBitrate.value),
+                subtitleStreamIndex: selectSubtitle.value === 'none' ? null : parseInt(selectSubtitle.value),
+                subtitleMethod: selectSubtitleMethod.value,
+                container: selectContainer.value
+            };
+
+            downloadUrl = buildDownloadUrl(currentApiClient, currentItem, options);
+
+            // Build filename in dotted notation
+            const resolutionName = selectResolution.options[selectResolution.selectedIndex].text.split(' ')[0];
+            const codecName = selectVideoCodec.value.toUpperCase();
+            const audioBitrateKbps = Math.round(options.audioBitRate / 1000);
+            const audioCodecName = selectAudioCodec.value.toUpperCase();
+
+            // Clean item name (replace spaces with dots, remove problematic characters)
+            const cleanName = currentItem.Name.replace(/\s+/g, '.').replace(/[^\w\.\-]/g, '');
+
+            // Format: Name.1080p.AV1.192kbps.AAC.mkv
+            filename = `${cleanName}.${resolutionName}.${codecName}.${audioBitrateKbps}kbps.${audioCodecName}.${options.container}`;
+            title = `${currentItem.Name} (${resolutionName} ${codecName})`;
+        }
+
+        fileDownloader.download([{
+            url: downloadUrl,
+            item: currentItem,
+            itemId: currentItem.Id,
+            serverId: currentApiClient.serverId(),
+            title: title,
+            filename: filename
+        }]);
+
+        toast('Download started');
+        dialogHelper.close(e.target.closest('.dialog'));
+    });
+
+    return false;
+}
+
+export function show(item, apiClient) {
+    currentItem = item;
+    currentApiClient = apiClient;
+
+    return new Promise((resolve) => {
+        const dlg = dialogHelper.createDialog({
+            removeOnClose: true,
+            size: 'medium'
+        });
+
+        dlg.classList.add('formDialog');
+
+        let html = globalize.translateHtml(template, 'core');
+        dlg.innerHTML = html;
+
+        // Populate dropdowns
+        populateQualityOptions(dlg, item);
+        populateAudioTracks(dlg, item);
+        populateSubtitles(dlg, item);
+        updateEstimatedSize(dlg, item);
+        updateCodecCompatibility(dlg); // Set initial state
+        updateAudioBitrateOptions(dlg); // Set recommended bitrates
+
+        // Event listeners
+        dlg.querySelector('#selectResolution').addEventListener('change', () => {
+            populateQualityOptions(dlg, item);
+            updateEstimatedSize(dlg, item);
+        });
+
+        dlg.querySelector('#selectQuality').addEventListener('change', () => {
+            updateEstimatedSize(dlg, item);
+        });
+
+        dlg.querySelector('#selectVideoCodec').addEventListener('change', () => {
+            updateCodecCompatibility(dlg);
+            populateQualityOptions(dlg, item);
+            updateEstimatedSize(dlg, item);
+        });
+
+        dlg.querySelector('#selectAudioTrack').addEventListener('change', () => {
+            updateAudioBitrateOptions(dlg);
+            updateEstimatedSize(dlg, item);
+        });
+
+        dlg.querySelector('#selectAudioCodec').addEventListener('change', () => {
+            updateCodecCompatibility(dlg);
+            updateAudioBitrateOptions(dlg);
+            updateEstimatedSize(dlg, item);
+        });
+
+        dlg.querySelector('#selectAudioBitrate').addEventListener('change', () => {
+            updateEstimatedSize(dlg, item);
+        });
+
+        dlg.querySelector('#selectContainer').addEventListener('change', () => {
+            updateCodecCompatibility(dlg);
+        });
+
+        dlg.querySelector('#selectSubtitle').addEventListener('change', () => {
+            updateSubtitleMethod(dlg);
+        });
+
+        dlg.querySelector('form').addEventListener('submit', onSubmit);
+
+        dlg.querySelector('.btnCancel').addEventListener('click', () => {
+            dialogHelper.close(dlg);
+        });
+
+        if (layoutManager.tv) {
+            import('../autoFocuser').then(({ default: autoFocuser }) => {
+                autoFocuser.autoFocus(dlg);
+            });
+        }
+
+        dialogHelper.open(dlg).then(() => {
+            resolve();
+        });
+    });
+}
+
+export default {
+    show: show
+};
diff --git a/src/components/downloadOptionsDialog/downloadOptionsDialog.scss b/src/components/downloadOptionsDialog/downloadOptionsDialog.scss
new file mode 100644
index 0000000000..6d168e75c2
--- /dev/null
+++ b/src/components/downloadOptionsDialog/downloadOptionsDialog.scss
@@ -0,0 +1,65 @@
+.verticalSection {
+    margin-bottom: 1.5em;
+
+    &:last-child {
+        margin-bottom: 0;
+    }
+}
+
+.sectionTitle {
+    margin: 0 0 0.75em 0;
+    font-size: 1.1em;
+    font-weight: 500;
+    color: rgba(255, 255, 255, 0.87);
+}
+
+.selectContainer {
+    margin-bottom: 1em;
+
+    &:last-child {
+        margin-bottom: 0;
+    }
+}
+
+.selectLabel {
+    display: block;
+    margin-bottom: 0.5em;
+    font-size: 0.95em;
+    color: rgba(255, 255, 255, 0.7);
+}
+
+.emby-select {
+    width: 100%;
+}
+
+.downloadInfo {
+    background: rgba(var(--primary-rgb), 0.1);
+    border-left: 3px solid rgba(var(--primary-rgb), 0.5);
+    padding: 1em;
+    border-radius: 4px;
+    margin-bottom: 8em;
+}
+
+#estimatedSize,
+#downloadDuration {
+    font-size: 0.95em;
+}
+
+#sizeValue,
+#durationValue {
+    color: rgba(var(--primary-rgb), 1);
+    font-weight: 500;
+}
+
+.formDialogFooter {
+    position: sticky;
+    bottom: 0;
+    background: var(--dialog-background, #202020);
+    padding: 1em 1.5em;
+    margin: 0 -1.5em;
+    border-top: 1px solid rgba(255, 255, 255, 0.1);
+    display: flex;
+    gap: 1em;
+    justify-content: flex-end;
+    z-index: 1000;
+}
diff --git a/src/components/downloadOptionsDialog/downloadOptionsDialog.template.html b/src/components/downloadOptionsDialog/downloadOptionsDialog.template.html
new file mode 100644
index 0000000000..be024f63c1
--- /dev/null
+++ b/src/components/downloadOptionsDialog/downloadOptionsDialog.template.html
@@ -0,0 +1,138 @@
+<div class="formDialogHeader">
+    <button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1">
+        <span class="material-icons arrow_back"></span>
+    </button>
+    <h3 class="formDialogHeaderTitle">Download Options</h3>
+</div>
+
+<form>
+<div class="formDialogContent smoothScrollY" style="padding: 1.5em 1.5em 1.5em 1.5em; max-height: 60vh; overflow-y: auto;">
+        <div class="verticalSection">
+            <h2 class="sectionTitle">Video Settings</h2>
+
+            <div class="selectContainer">
+                <label class="selectLabel" for="selectResolution">Resolution</label>
+                <select is="emby-select" id="selectResolution" class="emby-select-withcolor emby-select">
+                    <option value="original">Original (Source)</option>
+                    <option value="3840">4K (3840x2160)</option>
+                    <option value="2560">1440p (2560x1440)</option>
+                    <option value="1920" selected>1080p (1920x1080)</option>
+                    <option value="1280">720p (1280x720)</option>
+                    <option value="640">480p (640x480)</option>
+                </select>
+            </div>
+
+            <div class="selectContainer">
+                <label class="selectLabel" for="selectQuality">Quality</label>
+                <select is="emby-select" id="selectQuality" class="emby-select-withcolor emby-select"></select>
+            </div>
+
+            <div class="selectContainer">
+                <label class="selectLabel" for="selectVideoCodec">${LabelVideoCodec}</label>
+                <select is="emby-select" id="selectVideoCodec" class="emby-select-withcolor emby-select">
+                    <option value="copy">Copy Original (No Transcode)</option>
+                    <option value="h264">H.264 (Most Compatible)</option>
+                    <option value="hevc">HEVC/H.265</option>
+                    <option value="vp9">VP9</option>
+                    <option value="av1" selected>AV1</option>
+                </select>
+            </div>
+        </div>
+
+        <div class="verticalSection">
+            <h2 class="sectionTitle">Audio Settings</h2>
+
+            <div class="selectContainer">
+                <label class="selectLabel" for="selectAudioTrack">Audio Track</label>
+                <select is="emby-select" id="selectAudioTrack" class="emby-select-withcolor emby-select"></select>
+            </div>
+
+            <div class="selectContainer">
+                <label class="selectLabel" for="selectAudioCodec">${LabelAudioCodec}</label>
+                <select is="emby-select" id="selectAudioCodec" class="emby-select-withcolor emby-select">
+                    <option value="aac">AAC (Recommended)</option>
+                    <option value="ac3">AC3 (Dolby Digital)</option>
+                    <option value="eac3">E-AC3 (Dolby Digital Plus)</option>
+                    <option value="mp3">MP3</option>
+                    <option value="opus">Opus (WebM)</option>
+                    <option value="copy">Copy (No Transcode)</option>
+                </select>
+            </div>
+
+            <div class="selectContainer">
+                <label class="selectLabel" for="selectAudioBitrate">${LabelAudioBitrate}</label>
+                <select is="emby-select" id="selectAudioBitrate" class="emby-select-withcolor emby-select">
+                    <option value="1536000">1536 kbps</option>
+                    <option value="1024000">1024 kbps</option>
+                    <option value="768000">768 kbps</option>
+                    <option value="640000">640 kbps</option>
+                    <option value="512000">512 kbps</option>
+                    <option value="510000">510 kbps</option>
+                    <option value="450000">450 kbps</option>
+                    <option value="448000">448 kbps</option>
+                    <option value="384000">384 kbps</option>
+                    <option value="320000">320 kbps</option>
+                    <option value="256000">256 kbps</option>
+                    <option value="224000">224 kbps</option>
+                    <option value="192000" selected>192 kbps</option>
+                    <option value="160000">160 kbps</option>
+                    <option value="128000">128 kbps</option>
+                    <option value="96000">96 kbps</option>
+                    <option value="64000">64 kbps</option>
+                </select>
+            </div>
+        </div>
+
+        <div class="verticalSection">
+            <h2 class="sectionTitle">Subtitle Settings</h2>
+
+            <div class="selectContainer">
+                <label class="selectLabel" for="selectSubtitle">Subtitles</label>
+                <select is="emby-select" id="selectSubtitle" class="emby-select-withcolor emby-select">
+                    <option value="none" selected>None</option>
+                </select>
+            </div>
+
+            <div class="selectContainer" id="subtitleMethodContainer" style="display: none;">
+                <label class="selectLabel" for="selectSubtitleMethod">Subtitle Method</label>
+                <select is="emby-select" id="selectSubtitleMethod" class="emby-select-withcolor emby-select">
+                    <option value="Encode">Burn-in (Hardcoded)</option>
+                    <option value="Embed" selected>Embed (Soft Subtitle)</option>
+                </select>
+            </div>
+        </div>
+
+        <div class="verticalSection">
+            <h2 class="sectionTitle">Container Format</h2>
+
+            <div class="selectContainer">
+                <label class="selectLabel" for="selectContainer">Container</label>
+                <select is="emby-select" id="selectContainer" class="emby-select-withcolor emby-select">
+                    <option value="mp4">MP4</option>
+                    <option value="mkv" selected>MKV</option>
+                    <option value="webm">WebM</option>
+                </select>
+            </div>
+        </div>
+
+        <div class="verticalSection">
+            <div class="downloadInfo" style="padding: 1em; background: rgba(255,255,255,0.05); border-radius: 4px;">
+                <div id="estimatedSize" style="font-size: 1.1em; margin-bottom: 0.5em;">
+                    <strong>Estimated Size:</strong> <span id="sizeValue">Calculating...</span>
+                </div>
+                <div id="downloadDuration" style="color: rgba(255,255,255,0.7);">
+                    <strong>Duration:</strong> <span id="durationValue">-</span>
+                </div>
+            </div>
+        </div>
+    </div>
+
+<div class="formDialogFooter">
+    <button is="emby-button" type="button" class="raised button-cancel block btnCancel">
+        <span>${ButtonCancel}</span>
+    </button>
+    <button is="emby-button" type="submit" class="raised button-submit block">
+        <span>Download</span>
+    </button>
+</div>
+</form>
diff --git a/src/components/itemContextMenu.js b/src/components/itemContextMenu.js
index 7f07c203e4..1e1a86f9e7 100644
--- a/src/components/itemContextMenu.js
+++ b/src/components/itemContextMenu.js
@@ -13,6 +13,7 @@ import { playbackManager } from './playback/playbackmanager';
 import toast from './toast/toast';
 import * as userSettings from '../scripts/settings/userSettings';
 import { AppFeature } from 'constants/appFeature';
+import downloadOptionsDialog from './downloadOptionsDialog/downloadOptionsDialog';
 
 /** Item types that support downloading all children. */
 const DOWNLOAD_ALL_TYPES = [
@@ -410,18 +411,26 @@ function executeCommand(item, id, options) {
                 });
                 break;
             case 'download':
-                import('../scripts/fileDownloader').then((fileDownloader) => {
-                    const downloadHref = apiClient.getItemDownloadUrl(itemId);
-                    fileDownloader.download([{
-                        url: downloadHref,
-                        item,
-                        itemId,
-                        serverId,
-                        title: item.Name,
-                        filename: item.Path.replace(/^.*[\\/]/, '')
-                    }]);
-                    getResolveFunction(getResolveFunction(resolve, id), id)();
-                });
+                // Show download options dialog for videos, direct download for others
+                if (item.Type === 'Movie' || item.Type === 'Episode' || item.Type === 'Video') {
+                    downloadOptionsDialog.show(item, apiClient).then(() => {
+                        getResolveFunction(getResolveFunction(resolve, id), id)();
+                    });
+                } else {
+                    // Direct download for non-video items (books, music, etc.)
+                    import('../scripts/fileDownloader').then((fileDownloader) => {
+                        const downloadHref = apiClient.getItemDownloadUrl(itemId);
+                        fileDownloader.download([{
+                            url: downloadHref,
+                            item,
+                            itemId,
+                            serverId,
+                            title: item.Name,
+                            filename: item.Path.replace(/^.*[\\/]/, '')
+                        }]);
+                        getResolveFunction(getResolveFunction(resolve, id), id)();
+                    });
+                }
                 break;
             case 'downloadall': {
                 const downloadItems = items => {
diff --git a/src/components/playback/playersettingsmenu.js b/src/components/playback/playersettingsmenu.js
index 5b0aca301f..12b2488fc3 100644
--- a/src/components/playback/playersettingsmenu.js
+++ b/src/components/playback/playersettingsmenu.js
@@ -93,12 +93,16 @@ function getQualitySecondaryText(player) {
         return stream.Type === 'Video';
     })[0];
 
+    const videoCodec = videoStream ? videoStream.Codec : null;
+    const videoBitRate = videoStream ? videoStream.BitRate : null;
     const videoWidth = videoStream ? videoStream.Width : null;
     const videoHeight = videoStream ? videoStream.Height : null;
 
     const options = qualityoptions.getVideoQualityOptions({
         currentMaxBitrate: playbackManager.getMaxStreamingBitrate(player),
         isAutomaticBitrateEnabled: playbackManager.enableAutomaticBitrateDetection(player),
+        videoCodec,
+        videoBitRate,
         videoWidth: videoWidth,
         videoHeight: videoHeight,
         enableAuto: true
diff --git a/src/scripts/fileDownloader.js b/src/scripts/fileDownloader.js
index 24f1631017..dde5c18ae6 100644
--- a/src/scripts/fileDownloader.js
+++ b/src/scripts/fileDownloader.js
@@ -3,8 +3,7 @@ import shell from './shell';
 
 export function download(items) {
     if (!shell.downloadFiles(items)) {
-        multiDownload(items.map(function (item) {
-            return item.url;
-        }));
+        // Pass full item objects (with url and filename) to multiDownload
+        multiDownload(items);
     }
 }
diff --git a/src/scripts/multiDownload.js b/src/scripts/multiDownload.js
index c9f40f56a4..cef4c8a3bf 100644
--- a/src/scripts/multiDownload.js
+++ b/src/scripts/multiDownload.js
@@ -27,25 +27,35 @@ function fallback(urls) {
     })();
 }
 
-function download(url) {
+function download(url, filename) {
     const a = document.createElement('a');
-    a.download = '';
+    a.download = filename || '';
     a.href = url;
     a.click();
 }
 
-export default function (urls) {
-    if (!urls) {
-        throw new Error('`urls` required');
+export default function (items) {
+    if (!items) {
+        throw new Error('`items` required');
     }
 
+    // Support both old format (array of URLs) and new format (array of objects with url+filename)
+    const isOldFormat = typeof items[0] === 'string';
+
+    console.log('multiDownload received items:', items);
+    console.log('isOldFormat:', isOldFormat);
+
     if (typeof document.createElement('a').download === 'undefined' || browser.iOS) {
+        const urls = isOldFormat ? items : items.map(item => item.url || item);
         return fallback(urls);
     }
 
     let delay = 0;
 
-    urls.forEach(function (url) {
-        setTimeout(download.bind(null, url), 100 * ++delay);
+    items.forEach(function (item) {
+        const url = isOldFormat ? item : (item.url || item);
+        const filename = isOldFormat ? '' : (item.filename || '');
+        console.log('Downloading:', { url, filename });
+        setTimeout(download.bind(null, url, filename), 100 * ++delay);
     });
 }
