携帯電話などではお馴染みだが、Rangeヘッダーがついている場合は、
206 のステータスで部分的に返す必要がある。
safari でだけ再生されなかったが、 返しているデータバイト数が1バイト足りないためだった。
def main # 何かの方法で読み込む bin = load send_response bin end def send_response bin if headers["Range"].blank? send_data( bin, disposition: "inline", type: "audio/mp3", ) else match = request.headers['Range'].match /bytes=(\d+)-(\d*)/ file_size = bin.bytesize file_beg = match[1].to_i file_end = match[2].blank? ? (file_size - 1) : match[2].to_i response.header["Content-Range"] = "bytes #{file_beg}-#{file_end}/#{file_size}" response.header["Content-Transfer-Encoding"] = "binary" response.header["Content-Length"] = (file_end - file_beg + 1) status = file_end == (file_size - 1) ? "200 OK" : "206 Partial Content" send_data( bin.slice(file_beg, file_end + 1), disposition: "inline", type: "audio/mp3", status: status, ) end