2011-12-21 20 views
5

का उपयोग वीडियो वीडियो स्ट्रीमिंग के लिए दिया गया है। यह आईई 9 और फ़ायरफ़ॉक्स के साथ ठीक है लेकिन यह क्रोम और मैक सफारी के साथ ठीक नहीं है।एचटीएमएल 5 और सर्वलेट

import java.io.*; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

/** 
* Servlet implementation class VideoStreamServlet 
*/ 

public class VideoStreamServlet extends HttpServlet { 
    private static final long serialVersionUID = 1L; 

    /** 
    * Default constructor. 
    */ 
    public VideoStreamServlet() { 
     // TODO Auto-generated constructor stub 
    } 

    /** 
    * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) 
    */ 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     // TODO Auto-generated method stub 
     String range = request.getHeader("range"); 
     String browser = request.getHeader("User-Agent"); 
     System.out.println(browser); 
     if(browser.indexOf("Firefox") != -1){ 
      System.out.println("==========ITS FIREFOX============="); 
      byte[] data = getBytesFromFile(new File("D:/media/final.ogg")); 
      response.setContentType("video/ogg"); 
      response.setContentLength(data.length); 
      response.setHeader("Content-Range", range + Integer.valueOf(data.length-1)); 
      response.setHeader("Accept-Ranges", "bytes"); 
      response.setHeader("Etag", "W/\"9767057-1323779115364\""); 
      byte[] content = new byte[1024]; 
      BufferedInputStream is = new BufferedInputStream(new ByteArrayInputStream(data)); 
      OutputStream os = response.getOutputStream(); 
      while (is.read(content) != -1) { 
       //System.out.println("... write bytes"); 
       os.write(content); 
      } 
      is.close(); 
      os.close(); 
     } 

     else if(browser.indexOf("Chrome") != -1){ 
      System.out.println("==========ITS Chrome============="); 
      byte[] data = getBytesFromFile(new File("D:/media/final.mp4")); 
      String diskfilename = "final.mp4"; 
      response.setContentType("video/mp4"); 
      //response.setContentType("application/octet-stream"); 
      response.setHeader("Content-Disposition", "attachment; filename=\"" + diskfilename + "\""); 
      System.out.println("data.length " + data.length); 
      response.setContentLength(data.length); 
      response.setHeader("Content-Range", range + Integer.valueOf(data.length-1)); 
      response.setHeader("Accept-Ranges", "bytes"); 
      response.setHeader("Etag", "W/\"9767057-1323779115364\""); 
      byte[] content = new byte[1024]; 
      BufferedInputStream is = new BufferedInputStream(new ByteArrayInputStream(data)); 
      OutputStream os = response.getOutputStream(); 
      while (is.read(content) != -1) { 
       //System.out.println("... write bytes"); 
       os.write(content); 
      } 
      is.close(); 
      os.close(); 
     } 

     else if(browser.indexOf("MSIE") != -1) { 
      System.out.println("==========ITS IE9============="); 
      byte[] data = getBytesFromFile(new File("D:/media/final.mp4")); 
      String diskfilename = "final.mp4"; 
      response.setContentType("video/mpeg"); 
      //response.setContentType("application/octet-stream"); 
      response.setHeader("Content-Disposition", "attachment; filename=\"" + diskfilename + "\""); 
      System.out.println("data.length " + data.length); 
      response.setContentLength(data.length); 
      response.setHeader("Content-Range", range + Integer.valueOf(data.length-1)); 
      response.setHeader("Accept-Ranges", "text/x-dvi"); 
      response.setHeader("Etag", "W/\"9767057-1323779115364\""); 
      byte[] content = new byte[1024]; 
      BufferedInputStream is = new BufferedInputStream(new ByteArrayInputStream(data)); 
      OutputStream os = response.getOutputStream(); 
      while (is.read(content) != -1) { 
       //System.out.println("... write bytes"); 
       os.write(content); 
      } 
      is.close(); 
      os.close(); 
     } 
     else if(browser.indexOf("CoreMedia") != -1) { 
      System.out.println("============ Safari============="); 
      byte[] data = getBytesFromFile(new File("D:/media/final.mp4")); 
      String diskfilename = "final.mp4"; 
      response.setContentType("video/mpeg"); 
      //response.setContentType("application/octet-stream"); 
      response.setHeader("Content-Disposition", "attachment; filename=\"" + diskfilename + "\""); 
      System.out.println("data.length " + data.length); 
      //response.setContentLength(data.length); 
      //response.setHeader("Content-Range", range + Integer.valueOf(data.length-1)); 
      // response.setHeader("Accept-Ranges", " text/*, text/html, text/html;level=1, */* "); 
      // response.setHeader("Etag", "W/\"9767057-1323779115364\""); 
      byte[] content = new byte[1024]; 
      BufferedInputStream is = new BufferedInputStream(new ByteArrayInputStream(data)); 
      OutputStream os = response.getOutputStream(); 
      while (is.read(content) != -1) { 
       //System.out.println("... write bytes"); 
       os.write(content); 
      } 
      is.close(); 
      os.close(); 
     } 
    } 

    /** 
    * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 
    */ 
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     // TODO Auto-generated method stub 
    } 
    private static byte[] getBytesFromFile(File file) throws IOException { 
     InputStream is = new FileInputStream(file); 
     //System.out.println("\nDEBUG: FileInputStream is " + file); 
     // Get the size of the file 
     long length = file.length(); 
     //System.out.println("DEBUG: Length of " + file + " is " + length + "\n"); 
     /* 
     * You cannot create an array using a long type. It needs to be an int 
     * type. Before converting to an int type, check to ensure that file is 
     * not loarger than Integer.MAX_VALUE; 
     */ 
     if (length > Integer.MAX_VALUE) { 
      System.out.println("File is too large to process"); 
      return null; 
     } 
     // Create the byte array to hold the data 
     byte[] bytes = new byte[(int)length]; 
     // Read in the bytes 
     int offset = 0; 
     int numRead = 0; 
     while ((offset < bytes.length) 
       && 
       ((numRead=is.read(bytes, offset, bytes.length-offset)) >= 0)) { 
      offset += numRead; 
     } 
     // Ensure all the bytes have been read in 
     if (offset < bytes.length) { 
      throw new IOException("Could not completely read file " + file.getName()); 
     } 
     is.close(); 
     return bytes; 
    } 

} 
+0

कुछ नोट्स: आप जो कर रहे हैं वह "स्ट्रीमिंग" नहीं है, आप बस HTTP पर फ़ाइलों को किसी अन्य के रूप में सेवा दे रहे हैं; सर्वर स्तर पर विभिन्न ब्राउज़रों को संभालना एक बहुत बुरा विचार है (और सामान्य रूप से इसे जितना संभव हो उतना छोटा किया जाना चाहिए); आपको केवल 2-3 लाइनों को अलग करना चाहिए जो सभी कोड को दोहराने के बजाय प्रत्येक मामले के लिए अलग हैं। – Viruzzo

उत्तर

8

ईमानदारी से, यह दृष्टिकोण बिल्कुल सही नहीं है।

  • आप सर्वर साइड में उपयोगकर्ता एजेंट सूँघने और उस पर व्यापार नौकरी निर्भर करता है। यह सभी मामलों में एक बुरा विचार है। यदि आप चाहते हैं कि उपयोगकर्ता एजेंट के आधार पर एक अलग फ़ाइल निर्दिष्ट करें, तो जावास्क्रिप्ट या सीएसएस की मदद से इसे HTML पक्ष में करें। क्लाइंट साइड भाषा दोनों उपयोगकर्ता एजेंट स्ट्रिंग (जो अर्थात् स्पूफेबल है) को स्नीफ करने की आवश्यकता के बिना वास्तविक ब्राउज़र की पहचान करने में सक्षम हैं।

  • आप Range अनुरोधों पर सही ढंग से प्रतिक्रिया नहीं दे रहे हैं। आप अनुरोधित Range के बजाय पूरी फ़ाइल वापस भेज रहे हैं। फ़ायरफ़ॉक्स और आईई रेंज अनुरोधों का उपयोग नहीं करते हैं और यही कारण है कि यह "काम करता है"। क्रोम और सफारी रेंज अनुरोधों का उपयोग करें।

इस उपयोगकर्ता एजेंट सूँघने और ठीक से RandomAccessFile बजाय File और byte[] द्वारा Range अनुरोधों का जवाब देने के बिना संभव होना चाहिए। खाते में सभी HTTP specification आवश्यकताओं को लेने के लिए यह केवल बहुत ही कोड है, इसलिए यहां एक लिंक है जहां आप ऐसे सर्वलेट का ठोस उदाहरण पा सकते हैं: FileServlet supporting resume and caching

हालांकि, servletcontainer के डिफ़ॉल्ट सर्वलेट में नौकरी को प्रतिनिधि करना बेहतर है। यदि यह उदाहरण बिलाव के लिए है, तो तुम सब करने की जरूरत है /conf/server.xml के लिए निम्न पंक्ति जोड़ने के लिए है:

<Context docBase="D:\media" path="/media" /> 

इस तरह वांछित मीडिया फ़ाइलों को एक सर्वलेट homegrow की आवश्यकता के बिना सिर्फ http://localhost:8080/media/final.ogg और http://localhost:8080/media/final.mp4 द्वारा उपलब्ध हैं।

+1

धन्यवाद, यह मेरे लिए बहुत उपयोगी है "फाइलसेवलेट फिर से शुरू करने और कैशिंग का समर्थन करता है"। –

+0

टॉमकैट संदर्भ दृष्टिकोण के लिए: क्या मीडिया फ़ाइलों को अनुरोध फ़िल्टर लागू करने का कोई तरीका है? – jwi

0

Google क्रोम एच .264 (एमपी 4 शामिल नहीं है) का समर्थन नहीं करता है, इसलिए आपको Google क्रोम के साथ अंतिम.ओजीजी का उपयोग करने की आवश्यकता है। सफारी के लिए आप इस लाइन

browser.indexOf("CoreMedia") != -1 

बजाय "CoreMedia" के "सफारी"

मैं यह काम करता है आशा है कि जोड़ने को बदलने की जरूरत है।

1

यह प्रारूप समर्थन समस्या का अधिक प्रतीत होता है।

आप ओग प्रारूप का प्रयास कर सकते हैं। एचटीएमएल 5 कोड

<audio controls="controls"> 
  <source src="song.ogg" type="audio/ogg" /> 
  Your browser does not support the audio tag. 
</audio> 
0
String diskfilename = "final.mp4"; 
response.setHeader("Content-Disposition", "attachment; filename=\"" + diskfilename + "\""); 

बस इन दो पंक्तियों टिप्पणी और फिर क्रोम आपका वीडियो चल जाएगा पर चलाया जाता है।

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