У меня есть сценарий использования, когда пользователь хочет передать потоковый файл mp4 с сервера, а затем удалить его.
Код для потоковой передачи видео довольно прост и общеизвестен:
// Express.js
const fs = require('fs')
const { promisify } = require('util')
const stat = promisify(fs.stat)
// ...
router.get('/:sessionId', async (req, res) => {
let filePath = '/some/file/path'
const fileStat = await stat(filePath).catch(e => {
console.error('Video not found!', e)
return res.status(404).json({ message: 'Video not found!' })
})
try {
const fileSize = fileStat.size
const range = req.headers.range
if (range) {
const parts = range.replace(/bytes=/, '').split('-')
const start = parseInt(parts[0], 10)
const end = parts[1] ? parseInt(parts[1], 10) : fileSize - 1
const chunksize = end - start + 1
const file = fs.createReadStream(filePath, { start, end })
const head = {
'Content-Range': `bytes ${start}-${end}/${fileSize}`,
'Accept-Ranges': 'bytes',
'Content-Length': chunksize,
'Content-Type': 'video/mp4',
Connection: 'close'
}
res.writeHead(206, head)
file.pipe(res)
} else {
const head = {
'Content-Length': fileSize,
'Content-Type': 'video/mp4'
}
res.writeHead(200, head)
fs.createReadStream(filePath).pipe(res)
}
} catch (e) {
console.error(e)
res.status(500).json({ message: 'Server error when streaming the media' })
}
})
Для удаления файла я использую пакет del
.
К сожалению, после открытия видеопотока в браузере, его закрытия и попытки удалить видео я получаю сообщение об ошибке: EPERM: Operation not permitted, unlink...
.
В мониторе ресурсов Windows я вижу, что файл все еще открыт в 2 процессах node.exe, даже если вкладка браузера уже закрыта, и я полагаю, что это должно остановить поток чтения. Все файлы удаляются из каталога, кроме самого видео, которое нельзя открыть вручную, поскольку в Media Player отображается похожая ошибка: Windows Media Player cannot access the file. The file might be in use, you might not have access to the computer where the file is stored, or your proxy settings might not be correct.
Единственный способ удалить файл - перезапустить сервер, а затем попытаться удалить его, не запуская поток.
Не могу найти возможного объяснения, почему поток не закрывается и не позволяет удалить файл. Я предполагаю, что должна быть утечка памяти или какая-то ошибка разрешения файла в Windows, но я не могу попробовать этот проект на другой платформе, к сожалению. Файл хранится в подпапке в %LOCALAPPDATA%
.
Любая помощь будет высоко ценится.
Я использую 32-битный узел 10.13.0 в Windows 7 (бизнес-требования).