2013-05-08 6 views
9

हमें mp4s की सेवा करने में परेशानी हो रही है जो डिफ़ॉल्ट रेल 3 ऐप का उपयोग करके आईपैड पर खेलेंगे। डेस्कटॉप पर क्रोम और अन्य ब्राउज़रों में रूट देखने पर एमपी 4 सही ढंग से परोसा जाता है।आईपैड में रेल के माध्यम से एमपी 4 फ़ाइलों को सेवा करने का उचित तरीका क्या है?

file_path = File.join(Rails.root, 'test.mp4') 
send_file(file_path, :disposition => "inline", :type => "video/mp4") 

हम वीडियो देखने के लिए 0.0.0.0:3000/video/test.mp4 मारा और साथ प्रस्तुत कर रहे हैं iPad पर आइकन नहीं खेल सकते:

यहाँ हमारे कोड है। हमने विभिन्न शीर्षकों "सामग्री-लंबाई", "सामग्री-श्रेणी", आदि को संशोधित करने का प्रयास किया है, लेकिन वे अंतिम परिणाम को प्रभावित नहीं करते हैं।

हम भी कुछ हद

अर्थात

File.open(file_path, "r") do |f| 
    send_data f.read, :type => "video/mp4" 
end 

जब Ipad पर देखा एक ही वीडियो सार्वजनिक फ़ोल्डर से ठीक कार्य करता है send_data का उपयोग कर की कोशिश की है।

आईपैड में रेल के माध्यम से एमपी 4 फ़ाइलों को सेवा करने का उचित तरीका क्या है?

उत्तर

15

समस्या यह प्रतीत होती है कि रेल http-range अनुरोधों को संभाल नहीं पाती हैं जिन्हें आईओएस स्ट्रीमिंग के लिए आईओएस की आवश्यकता होती है।

यह विकास के लिए हमारे समाधान, (हमारे सर्वर के रूप में पतली उपयोग करते हुए) था:

if(request.headers["HTTP_RANGE"]) && Rails.env.development? 

    size = File.size(file_path) 
    bytes = Rack::Utils.byte_ranges(request.headers, size)[0] 
    offset = bytes.begin 
    length = bytes.end - bytes.begin + 1 

    response.header["Accept-Ranges"]= "bytes" 
    response.header["Content-Range"] = "bytes #{bytes.begin}-#{bytes.end}/#{size}" 
    response.header["Content-Length"] = "#{length}" 

    send_data IO.binread(file_path,length, offset), :type => "video/mp4", :stream => true, :disposition => 'inline', 
       :file_name => file_name 

    else 
    send_file(file_path, :disposition => 'inline', :stream => true, :file_name => file_name) 
    end 

अंतत: हम nginx XSendfile का उपयोग किया जाएगा ऊपर समाधान के रूप में हमारे उत्पादन वातावरण में संपत्ति की सेवा के लिए तुलना में बहुत धीमी है क्या ज़रुरत है।

+2

मुझे लगता है कि कोड में एक fencepost त्रुटि है। मेरा मानना ​​है कि लंबाई 'bytes.end - bytes.begin + 1' होनी चाहिए - यदि बाइट रेंज बाइट 10 से 12 तक है, तो यह 3 बाइट होना चाहिए। साथ ही, यदि आप किसी कारण से 'send_data' का उपयोग कर रहे हैं, तो प्रतिक्रिया शीर्षलेख में 'सामग्री-लंबाई' सेट करना सुनिश्चित करें। – tovodeverett

+0

इस समाधान के लिए धन्यवाद! मैंने @tovodeverett टिप्पणी के आधार पर सुधार जोड़ा। विकास के लिए सिनात्रा (रेल के बजाए) का उपयोग करके, मैंने sinatra/स्ट्रीमिंग contrib का उपयोग करके send_data व्यवहार को दोहराने में कामयाब रहे: 'stream {| out | out.write IO.binread (file_path, लंबाई, ऑफ़सेट); out.flush} ' –

+1

समाधान के लिए धन्यवाद! हमने देखा है कि क्रोम में इस दृष्टिकोण को करने के क्रम में किसी को प्रतिक्रिया स्थिति को '206' पर स्पष्ट रूप से सेट करना होगा। –

संबंधित मुद्दे

 संबंधित मुद्दे