私は古いgrails 2.5.1アプリで、サーバーから提供されたmp4ビデオファイルがSafariで再生されないことに気付きました。私はSOの問題を見て、それがレンジヘッダーと関係があるというヒントを得ました。しかし、私はレンジヘッダーを扱っている方法が間違っていると思う。grailsの範囲ヘッダーでHTTP経由でmp4リクエストをストリーミング
今まで私が見つけたのは、Mac OS Safari 11.0(11604.1.38.1.7)です(今はiOS Safariについて気にしません).2つのGETリクエストを送信します。第一に、それはとの1を送信します。その後、それは第二GETリクエストを送信し
host: localhost:8080
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Safari/604.1.38
accept-language: en-us
accept-encoding: gzip, deflate
x-request-time: t=****
x-forwarded-for: *.*.*.*
x-forwarded-host: *.com
x-forwarded-server: *.com
connection: Keep-Alive
cookie: ...TOO BIG TO SHOW HERE
<- "GET /.../videos/lol.mp4 HTTP/1.1" 200 186ms
:Safariウェブ検査官があまりお見せしていないため
host: localhost:8080
language: en-us
playback-session-id: 03F1B4E6-F97E-****
bytes=0-1
accept: */*
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Safari/604.1.38
https://.../videos/lol.mp4
encoding: identity
request-time: t=****
forwarded-for: *.*.*.*
forwarded-host: *.com
forwarded-server: *.com
connection: Keep-Alive
cookie: ...TOO BIG TO SHOW HERE
<- "GET /uiv2/videos/lol.mp4 HTTP/1.1" 206 149ms
はこれをデバッグすることは困難です。実際、それはあなたにすべてのヘッダーを表示しないので、私はバックエンドからこれを取得しなければなりませんでした。理解できるように、要求1と2との間の違いは、第2のものがplayback-session-idと範囲を有することである。
難しい部分は、範囲と再生セッションIDの処理方法をSafariに教える方法を見つけることです。
リクエストされている場合は、要求されたバイトの範囲を返すコントローラを作成しました。しかし、まだ運がありません。 Safariのコンソールで
import grails.compiler.GrailsTypeChecked
import grails.plugin.springsecurity.annotation.Secured
import asset.pipeline.grails.AssetResourceLocator
import grails.util.BuildSettings
import org.codehaus.groovy.grails.commons.GrailsApplication
import org.springframework.core.io.Resource
class VideoController {
GrailsApplication grailsApplication
AssetResourceLocator assetResourceLocator
public index() {
Resource mp4Resource = assetResourceLocator.findAssetForURI('/../lol.mp4');
response.addHeader("Content-type", "video/mp4")
response.addHeader('Accept-Ranges', 'bytes')
String range = request.getHeader('range')
if(range) {
String[] rangeKeyValue = range.split('=')
String[] rangeEnds = rangeKeyValue[1].split('-')
if(rangeEnds.length > 1) {
int startByte = Integer.parseInt(rangeEnds[0])
int endByte = Integer.parseInt(rangeEnds[1])
int contentLength = (endByte - startByte) + 1
byte[] inputBytes = new byte[contentLength]
mp4Resource.inputStream.read(inputBytes, startByte, contentLength)
response.status = 206
response.addHeader('Content-Length', "${contentLength}")
response.outputStream << inputBytes
} else {
response.addHeader('Content-Length', "${mp4Resource.contentLength()}")
response.outputStream << mp4Resource.inputStream
}
} else {
log.info 'no range, so responding with whole mp4'
response.addHeader('Content-Length', "${mp4Resource.contentLength()}")
response.outputStream << mp4Resource.inputStream
}
}
}
、私は取得しない:他に
Failed to load resource: Plug-in handled load
何を。そして悲しいことに、Webインスペクタのフィールドは、明らかにサーバーに設定されていても空白です。
私は任意のヘルプ、ポインタ、ヒントが理解されるであろうことをこの時点でたくさんのことを試してみました。みんなありがとう :) !