我有一个应用程序,旨在从我们的本地数据库流回视频.昨天我花了很多时间试图将数据返回成功RangeFileContentResult或RangeFileStreamResult不成功.
简而言之,当我将文件作为这两个结果中的任何一个返回时,我似乎无法正确地传输视频(或者根本不播放).
来自浏览器的请求将通过以下标头发送:
Range: bytes=0-
Run Code Online (Sandbox Code Playgroud)
并且提供的响应以这些标头为例:
Accept-Ranges: bytes
Content-Range: bytes 0-5103295/5103296
Run Code Online (Sandbox Code Playgroud)
在网络流量方面,我获得了一系列206的部分结果,然后是200结尾(根据小提琴手),这似乎是正确的.Chrome的网络标签不同意这一点,并看到一个初始请求(总是13个字节,我假设是握手)然后是一些状态为已取消或待处理的请求.据我所知,这或多或少是正确的,206 - 取消,206 - 取消等.但视频永远不会播放.
如果我将结果从我的控制器切换到FileResult,视频播放和Chrome,IE10和Firefox似乎在下载完成之前开始播放(感觉有点像它的流媒体!虽然我怀疑它不是)
但是随着范围的结果,我在chrome或IE中得不到任何东西,整个视频在firefox中下载了一滴.
据我所知,RangeFileContentResult应该处理响应客户端的一系列字节要下载(我的似乎没有,它只是告诉它获取整个文件(由上面的响应说明)).客户应该对此做出回应,而这似乎并没有.
有没有人对这方面有任何想法?特别:
a)应该RangeFileContentResult将一系列字节发送回客户端吗?b)有没有办法可以明确控制客户端请求的字节范围?c)在请求时,是否有任何理由或错误导致浏览器根本不加载视频RangeFileContentResult?
编辑:添加了一个图表,以帮助描述我所看到的:

编辑2:好的,所以情节变浓了.在使用RangedFile gubbins的同时,我们需要推出另一个系统测试版本,并将"RangeFileContentResult"留在我的控制器操作上,如下所示:
private ActionResult RetrieveVideo(MediaItem media)
{
return new RangeFileContentResult(
media.Content,
media.MimeType,
media.Id.ToString(),
DateTime.Now);
}
Run Code Online (Sandbox Code Playgroud)
奇怪的是,这似乎在我们的Azure系统测试环境中按预期工作,但仍然不在我的本地计算机上.我想知道是否有一些基于IIS的东西在Azures IIS8上运行得很开心,但在我的本地7.5实例上却没有?
我使用现有材料(使用Node)动态创建了未知长度的ZIP归档文件,该文件已被压缩。在ZIP存档中,文件仅被存储;ZIP仅用于单个容器。这就是为什么缓存创建的ZIP文件没有任何意义-不涉及任何实际计算。
到目前为止,还可以。现在,我想允许恢复下载,并且正在阅读有关Accept-Range,Range和Content-Range HTTP标头的信息。下载中断的客户会要求开放范围,例如:Range: bytes=8000000-。
我该如何回答?根据RFC 2616§14.16,我的答案必须包含一个Content-Range标头,并且在其中:
与byte-ranges-specifier值不同(请参见14.35.1),byte-range-resp-spec必须仅指定一个范围,并且必须包含该范围的第一个字节和最后一个字节的绝对字节位置。
因此,我不能只发送“从位置X开始的所有内容”,我还必须指定发送的最后一个字节-通过仅发送一部分已知大小,或通过预先计算长度。这两种想法都不适合我的情况。还有其他可能性吗?
是否有人在通过 HTTP 协议流式传输视频时使用范围标头实现了搜索?
我们已经使用范围标头实现了通过 http 协议流式传输视频的服务器,如果我们通过 Chrome 浏览器播放它,它可以正常工作。
但在android中,VideoView和MediaPlayer能够流式传输数据。但流式传输时出现问题。
1)当我们使用MediaPlayer时,我们只能搜索缓冲的视频。如果我们尝试寻找缓冲区之外的内容,它就会停止播放。
2)我们尝试使用Vitamio库,但它不允许我们进行查找。但它从头开始播放。(不知道为什么)
为了提供一些上下文,我有一个<video>标记,该标记具有src指向我的 node.js 服务器上的方法的属性。该方法mp4从另一台服务器获取文件,或者更确切地说是文件的一部分mp4,具体取决于Range浏览器指定的HTTP 标头,例如 - Range:bytes=0-。
预期行为(Chrome 行为)
为了防止我的 node.js 服务器从第三方服务器下载整个文件,我实现了大约 5MB 的最大缓冲区,以便一次下载。因此,如果用户发送请求以获取带有标题的视频
GET /play-test/videoId HTTP/1.1
Host: 127.0.0.1:8000
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Accept-Encoding: identity;q=1, *;q=0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
Accept: */*
Referer: http://127.0.0.1:8000/movie/99861
Accept-Language: en-US,en;q=0.8,es;q=0.6
Range: bytes=0-
Run Code Online (Sandbox Code Playgroud)
..然后我的服务器将响应
HTTP/1.1 206 Partial Content
X-Powered-By: Express
Content-Range: bytes 0-5000000/415473786
Connection: keep-alive
Accept-Ranges: bytes
Content-Length: 5000001
Content-Type: video/mp4
Date: …Run Code Online (Sandbox Code Playgroud) 我有支持视频内容的 HTTP Range 标头的 Web 服务器,并且Web Browsers and iOS效果很好,但是在使用 basic 开始对 Android 应用程序进行测试后,VideoView我发现该应用程序没有使用Range: 0-HTTP 标头发出请求。
我一开始就尝试根据 HTTP Range 标头规范使用此标头进行响应。发送 2 个字节的文件头,然后客户端将发送响应范围。
Accept-Ranges: bytes
Connection: keep-alive
Pragma: public
Content-Type: video/mp4
Content-Length: 2
Content-Range: 0-1/34568
Run Code Online (Sandbox Code Playgroud)
在 iOS 和 Web 浏览器上可以很好地处理此问题,但 Android根本VideoView不发送标头。Range
如何使这个工作VideoView?
“范围:字节=0-”标头是什么意思?是整个文件吗?我尝试发送回 0 个字节,但不起作用,当我发送整个文件时,它可以工作,但我在流上下文中多次收到此请求,它看起来不正确。
我有一个<video>and<audio>元素,它通过范围请求从我的服务器加载文件(mp4、mp3,无关紧要)。
然而,该元素似乎只从我的服务器请求结束范围,并从那里开始尝试直接从字节 0 流到末尾,导致播放器陷入“下载循环”,这使得浏览器暂停所有内容其他操作直至下载完成。
有谁知道这个问题的解决方案?例如,我是否必须使我的流请求有一个实际的结束content length或accept-ranges?
这是来自 Chrome 的完整请求列表,在底部您可以看到对该 url 的请求view?watch=v__AAAAAA673pxX一直处于待处理状态,基本上直到element.
简而言之:在使用http-range请求时,html5 元素会陷入下载循环,并导致所有其他请求保持“待处理”状态。
更新
该问题已在服务器端得到解决。
虽然原始流函数实际上会输出每个字节,但我修改了代码以仅输出实际缓冲区的大小。这迫使系统elements对剩余数据发出新请求。
这里的一个重要注意事项是返回content-length, ,accept-ranges并且content-ranges与每个请求中的文件大小、开始和结束位置相匹配HTTP RANGE。
供将来参考:
function stream(){
$i = $this->start;
set_time_limit(0);
while(!feof($this->stream) && $i <= $this->end) {
$bytesToRead = $this->buffer;
if(($i+$bytesToRead) > $this->end) {
$bytesToRead = $this->end - $i + 1;
}
$data = fread($this->stream, $bytesToRead);
echo $data;
flush();
$i += …Run Code Online (Sandbox Code Playgroud) 我正在尝试将文件缓冲区下载到5个线程中,但似乎出现乱码。
from numpy import arange
import requests
from threading import Thread
import urllib2
url = 'http://pymotw.com/2/urllib/index.html'
sizeInBytes = r = requests.head(url, headers={'Accept-Encoding': 'identity'}).headers['content-length']
splitBy = 5
splits = arange(splitBy + 1) * (float(sizeInBytes)/splitBy)
dataLst = []
def bufferSplit(url, idx, splits):
req = urllib2.Request(url, headers={'Range': 'bytes=%d-%d' % (splits[idx], splits[idx+1])})
print {'bytes=%d-%d' % (splits[idx], splits[idx+1])}
dataLst.append(urllib2.urlopen(req).read())
for idx in range(splitBy):
dlth = Thread(target=bufferSplit, args=(url, idx, splits))
dlth.start()
print dataLst
with open('page.html', 'w') as fh:
fh.write(''.join(dataLst))
Run Code Online (Sandbox Code Playgroud)
更新: 所以我努力了,但是进展甚微,但是,如果我下载jpg,则似乎已损坏;
from numpy import arange
import …Run Code Online (Sandbox Code Playgroud) http-range ×8
android ×2
http ×2
c# ×1
firefox ×1
html ×1
html5-video ×1
http-1.1 ×1
http-headers ×1
javascript ×1
lib.web.mvc ×1
node.js ×1
php ×1
python ×1
resume ×1
urllib2 ×1
video ×1