2012-02-19 11 views
6

मैं एक * .mov फ़ाइल को जेएवीई का उपयोग करके * .mp4 फ़ाइल में ट्रांसकोड करने का प्रयास कर रहा हूं, जो ffmpeg को कॉल करता है। इनपुट इनपुट और आउटपुट फ़ाइल दोनों इनपुटस्ट्रीम और आउटपुटस्ट्रीम रूपों में हैं। इसका मतलब है कि मुझे fputpeg के लिए इनपुटस्ट्रीम और आउटपुटस्ट्रीम के रूप में -i और -y parematers को पास करने की आवश्यकता है। मैं यह कैसे कर सकता हूं?ट्रांसकोड करने के लिए ffmpeg पर फ़ाइल इनपुटपुट स्ट्रीम और स्ट्रीमऑटपुटस्ट्रीम (JAVE-Java ऑडियो वीडियो एन्कोडिंग का उपयोग करके)

//Read a movfile.mov converted into a FileInputStream 
    InputStream fileInputStream = getFileInputStream(); 
    OutputStream fileOutputStream = new FileOutputStrea(outputMP4File) //Output   
    Process p = Runtime.exec("ffmpeg -i - -y -"); 
    InputStream pInStrm = p.getInputStream(); 
    OutputStream pOutStrm = p.getOutputStream(); 
    int vin = 0, vout = 0; 

    Thread read = new Thread() { 
     byte[] buff = new byte[4096]; 
      void run() { 
      while ((vin=fileInputStream.read(buf))!=-1) { 
       pOutStrm.write(buf, 0, vin); 
      } 
     } 
     }; read.start(); 

    Thread write = new Thread() { 
     byte[] buff = new byte[4096]; 
     void run() { 
      while ((vout=pInStrm.read(buf))!=-1) { 
       fileOutputStream.write(buf, 0, vout); 
      } 
     } 
     }; write.start(); 

लेकिन मुझे "IOException: पाइप बंद है" त्रुटि मिल रही है। क्या कोई मेरी मदद कर सकता है? वैकल्पिक रूप से अगर कोई जावा एपीआई कि इस ट्रांसकोडिंग (Windows और RedHat लिनक्स पर) कर सकता है, कि बहुत मददगार

धन्यवाद

उत्तर

3

है कि जिस तरह से काम करने के लिए नहीं जा रहा है हो सकता है।

याद रखें कि Jave महज एक ffmpeg निष्पादन, है कि आप पैरामीटर की आपूर्ति, लक्ष्य एन्कोडिंग, प्रबलता, आदि और की तरह तो मूल रूप से Jave बता fmpeg फोन और सेटिंग्स पारित करने के लिए करने के लिए एक आवरण के रूप में कार्य करता है, आप का उपयोग करके डाला Ffmpeg निष्पादन योग्य के पैरामीटर के रूप में जावा विधियां।

यह कदम सेटिंग्स, आप कर रहे हैं निर्दिष्ट करें कि आवश्यकता है 1. Serializable 2. ffmpeg निष्पादन

अब आप तर्क दे सकते हैं कि कम से कम कुछ InputStreams, FileInputStream की तरह, किसी भी तरह serializable हैं के रूप में वहाँ है करने के लिए जाना जाता है एक निम्न स्तर फ़ाइल डिस्क्रिप्टर जो इस इनपुट स्ट्रीम में से मेल खाता है, लेकिन बाइटएरेइन इनपुट स्ट्रीम पर विचार करें - मुझे नहीं पता कि जावा प्रत्येक प्लेटफ़ॉर्म पर लागू होता है लेकिन मुझे कोई संदेह है कि संबंधित फाइल डिस्क्रिप्टर है।

हालांकि महत्वपूर्ण बिंदु यह है कि एक ffmpeg निष्पादन योग्य नहीं है और नहीं जानता कि जावा ऑब्जेक्ट प्रकार इनपुट इनपुट क्या है। सबसे अच्छा यह (कम से कम पॉज़िक्स सिस्टम पर) कर सकता है एक पूर्णांक संख्या (फाइल डिस्क्रिप्टर) लेता है और इससे डेटा पढ़ने की कोशिश करता है। हालांकि, फ़ाइल डिस्क्रिप्टर के साथ काम करते समय बहुत सी चीजें गलत हो सकती हैं। उदाहरण के लिए यह खोज योग्य हो सकता है, अगर यह फ़ाइल है, उदाहरण के लिए या नहीं, तो यह वास्तव में सॉकेट से पढ़ने वाले डेटा का प्रतिनिधित्व करता है।

ग्लेडली, पॉज़िक्स सिस्टम पर, प्रत्येक प्रक्रिया के लिए कम से कम 3 फ़ाइल डिस्क्रिप्टर, हैं जो एसटीडीआईएन, एसटीडीओटीटी और एसटीडीईआरआर हैं। यह एक अवधारणा से मेल खाता है जहां आप एक प्रक्रिया से दूसरे प्रक्रिया में पाइप इनपुट/आउटपुट कर सकते हैं। मुझे नहीं पता कि यह विंडोज पर पर काम करता है, लेकिन ओएसएक्स या लिनक्स पर आप डेटा को ffmpeg निष्पादन योग्य में पाइप कर सकते हैं। यह वास्तव में इसका मतलब है, कि आप एसटीडीआईएन फाइल डिस्क्रिप्टर से पढ़ने के लिए ffmpeg को निर्देश देते हैं।

अफसोस की बात है, जेएवीई ffmpeg की इस विशेष सुविधा को लागू नहीं करता है, यानी कोई विधि नहीं है, जो पाइप डेटा ffmpegs STDIN में पाइप करता है।

FWIW।आप कुछ देशी (C/C++) कोड लिख सकता है और एक जावा वस्तु नीचे से गुजरती हैं 'DecodeFeed', JNI (http://en.wikipedia.org/wiki/Java_Native_Interface) कि रखती है दोनों एक InputStream और एक OutputStream

मूल कोड का उपयोग कर, आप लिखने के लिए शामिल हो सकते हैं है ffmpeg स्रोतों और उन्हें का उपयोग डीकोड/ट्रांसकोड इनपुट को डीकोडफिड.in से पढ़ा जाता है और फिर DecodeFeed.out पर लिखा जाता है।

मैं एंड्रॉइड प्रोजेक्ट में ऐसा कर रहा हूं, तो आप संदर्भ के लिए देखना चाहेंगे। https://github.com/fscz/FFmpeg-Android

वैकल्पिक रूप से, आप जावा को फोर्क कर सकते हैं और इस सुविधा को स्वयं लागू कर सकते हैं। जैसा कि आप जानते हैं कि जावा Runtime.exec पर कॉल करके निष्पादन योग्य चलाने का एक तरीका प्रदान करता है। यह कॉल प्रोसेस क्लास का एक उदाहरण वापस कर देगा जो Process.getOutputStream प्रदान करता है। यदि आप इस आउटपुटस्ट्रीम को लिखते हैं, तो आप वास्तव में केवल बनाई गई प्रक्रिया की STDIN पर लिखते हैं।

कैसे अंडे और एक प्रक्रिया के लिए लिखने के लिए प्रलेखन के लिए http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html देखें।

और http://ffmpeg.org/ffmpeg.html (STDIN से पढ़ने सहित) ffmpeg के लिए उपलब्ध कमांड लाइन विकल्प के लिए देखते हैं।