如何在Angular中通过本地存储的视频路径直接播放本地视频
问题根因
浏览器出于安全沙箱强制限制,禁止Web页面直接通过本地文件绝对路径(比如C:\My Videos\UploadedVideo.mp4)读取本地资源,哪怕你持有完整路径字符串也不能直接赋值给video的src属性,该限制没有通用绕过方法。
可行实现方案
方案1:使用File System Access API(纯Web场景,适用现代浏览器)
该API支持在用户首次授权后,持久化获取本地文件/目录的访问权限,无需用户每次打开应用都重新选择文件:
- 首次加载合集时,引导用户一次性授权你的视频存储目录的访问权限,通过
window.showDirectoryPicker()调用拿到目录句柄后,将句柄存储到indexedDB中,后续打开应用可直接读取,无需重复授权 - 匹配到对应视频的文件句柄后,调用
fileHandle.createObjectURL()生成临时blob链接,赋值给video的src属性即可正常播放 - 关键代码示例:
// 首次授权获取目录句柄,存储到indexedDB async function getVideoDirHandle() { const dirHandle = await window.showDirectoryPicker(); // 此处省略将dirHandle存储到indexedDB的逻辑 return dirHandle; } // 后续根据存储的路径字符串生成视频可播放链接 async function getVideoSrc(videoPath: string, dirHandle: FileSystemDirectoryHandle) { // 拆分路径、过滤盘符 const pathSegments = videoPath.split('\\').filter(seg => seg && !seg.includes(':')); let currentHandle: any = dirHandle; // 逐层查找目录 for (const seg of pathSegments.slice(0, -1)) { currentHandle = await currentHandle.getDirectoryHandle(seg); } // 拿到视频文件句柄 const videoFileHandle = await currentHandle.getFileHandle(pathSegments.at(-1)); const file = await videoFileHandle.getFile(); return URL.createObjectURL(file); }
注意:该API需要页面运行在HTTPS或者localhost环境下,兼容Chrome 86+、Edge 86+、Safari 15.2+版本浏览器
方案2:打包为Electron桌面应用(全兼容场景)
如果你的应用需要兼容更多环境,直接打包为Electron应用即可绕过浏览器沙箱限制:
- 正式场景建议注册自定义协议处理本地文件请求,避免关闭安全策略带来的风险,主进程代码示例:
const { protocol } = require('electron'); const path = require('path'); protocol.registerFileProtocol('local-video', (request, callback) => { const filePath = decodeURIComponent(request.url.replace('local-video://', '')); callback({ path: filePath }); });
- 渲染层直接把本地路径拼接为
local-video://C:\My Videos\UploadedVideo.mp4赋值给video的src即可播放,无需用户做任何授权操作
Angular适配注意事项
Angular默认会拦截非信任的资源链接,你需要自定义安全管道跳过XSS校验,才能正常绑定生成的播放链接:
// safe-url.pipe.ts import { Pipe, PipeTransform } from '@angular/core'; import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; @Pipe({ name: 'safeUrl' }) export class SafeUrlPipe implements PipeTransform { constructor(private sanitizer: DomSanitizer) {} transform(url: string): SafeUrl { return this.sanitizer.bypassSecurityTrustUrl(url); } }
模板中使用方式:
<video [src]="videoSrc | safeUrl" controls></video>
内容的提问来源于stack exchange,提问作者GyroGoober
相关产品推荐
相关产品推荐

