2010-10-06 18 views
25

मैं डेटा स्रोत को एक अलग फ़ाइल में सेट करने के लिए ऑनकंप्लिशन लिस्टर लागू करके वापस ठीक से वीडियो चला सकता हूं। वहां कोई समस्या नहीं है। मैं रीसेट() और तैयार() बस ठीक कहता हूं।एंड्रॉइड: मीडियाप्लेयर गैपलेस या सीमलेस वीडियो प्लेइंग

जो मैं समझने में सक्षम नहीं हूं, डेटा स्रोत परिवर्तन और नए वीडियो के बीच 1-2 सेकंड अंतराल स्क्रीन फ़्लिकर से छुटकारा पाने का तरीका है। अंतराल एक ब्लैक स्क्रीन दिखाता है, और मुझे इसके चारों ओर जाने का कोई रास्ता नहीं मिला है।

मैंने किसी छवि को मूल दृश्य की पृष्ठभूमि सेट करने का प्रयास किया है, लेकिन यह इसे बाईपास करने का प्रबंधन करता है। भले ही SurfaceView पारदर्शी है (जो डिफ़ॉल्ट रूप से है।) मैंने एक ही समय में कई वीडियो फ़ाइलों को चलाने की कोशिश की है, और जब कोई समाप्त होता है और दूसरा शुरू होता है तो मध्यस्थता के प्रदर्शन को स्विच करना भी होता है।

आखिरी चीज़ जो मैंने कोशिश की थी, उस पृष्ठभूमि में दूसरा दृश्य होना था जो वीडियो अस्थायी रूप से दिखाता है जबकि वीडियो "तैयारी" करता है और वीडियो को शुरू करने के लिए तैयार होने पर इसे हटा देता है। वह भी निर्बाध नहीं था।

क्या उस अंतर से छुटकारा पाने का कोई तरीका है। एक लूप में एक वीडियो चलाने से आश्चर्यजनक रूप से काम करता है और मैं अपवाद के साथ वही करता हूं जो कि मैं एक अलग वीडियो को देखने के बजाए एक ही वीडियो को देख रहा हूं। बहुत ज्यादा यह पता लगाने की कैसे "अंतर" बिना लगातार वीडियो खेलने के लिए, मैं 'की कोशिश कर बर्बाद समय

main.xml

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:background="@drawable/background" 
    android:layout_height="fill_parent"> 
    <SurfaceView 
     android:id="@+id/surface" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:layout_gravity="center"> 
    </SurfaceView> 
</FrameLayout> 

Player.java

public class Player extends Activity implements 
     OnCompletionListener, MediaPlayer.OnPreparedListener, SurfaceHolder.Callback { 
     private MediaPlayer player; 
    private SurfaceView surface; 
    private SurfaceHolder holder; 

    public void onCreate(Bundle b) { 
     super.onCreate(b); 
     setContentView(R.layout.main); 
     surface = (SurfaceView)findViewById(R.id.surface); 
     holder = surface.getHolder(); 
     holder.addCallback(this); 
     holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  
    } 

    public void onCompletion(MediaPlayer arg0) { 
     File clip = new File(Environment.getExternalStorageDirectory(),"file2.mp4"); 
     playVideo(clip.getAbsolutePath()); 
    } 
    public void onPrepared(MediaPlayer mediaplayer) { 
     holder.setFixedSize(player.getVideoWidth(), player.getVideoHeight()); 
     player.start(); 
    } 

    private void playVideo(String url) { 
     try { 
      File clip = new File(Environment.getExternalStorageDirectory(),"file1.mp4"); 

      if (player == null) { 
       player = new MediaPlayer(); 
       player.setScreenOnWhilePlaying(true); 
      } 
      else { 
       player.stop(); 
       player.reset(); 
      } 
      player.setDataSource(url); 
      player.setDisplay(holder); 
      player.setOnPreparedListener(this); 
      player.prepare(); 
      player.setOnCompletionListener(this); 
     } 
     catch (Throwable t) { 
      Log.e("ERROR", "Exception Error", t); 
     } 
    } 
+0

हालांकि इसे कुछ समय पहले पोस्ट किया गया है, मुझे एक ही समस्या का सामना करना पड़ रहा है। वीडियोव्यू का उपयोग करने के साथ भी, वीडियो के बीच स्विच करते समय भी मुझे एक अंतर होता है। क्या इसे हल करने का कोई और तरीका है? – dulys

उत्तर

2

के बाद मैं असंभव की ओर झुकाव। बेशक जब तक आप मूल स्तर पर खोदने और अपने स्वयं के खिलाड़ी को लागू करने में सक्षम नहीं होते हैं, तो एंड्रॉइड का मीडिया प्लेयर बस इस समय के रूप में निर्बाध प्लेबैक का समर्थन नहीं करता है।

+0

मैंने इसे एक हैक के माध्यम से हासिल किया है। मैं एक सेवा में 2 mediaplayer उदाहरणों के बीच टॉगल। मेरे पास एक कॉन्फ़िगर करने योग्य int वैरिएबल है जैसे कि मैं मीडिया एसेट ए समाप्त होने से पहले मीडिया एसेट बी "एन" सेकेंड खेलना शुरू करता हूं। – Krafty

+0

यह अच्छा है, लेकिन अनुभव से मैं आपको बता सकता हूं कि एक ही डिवाइस पर भी परीक्षण करना, सटीक समय सेट करना लगभग असंभव है, क्योंकि डिवाइस कभी-कभी मेमोरी पर कम चला सकता है, जिससे संक्रमण अचूक हो जाता है। – josephus

+0

@ user721448 किसी भी मामले में, मैं आपको अपने कोड को यहां एक उत्तर के रूप में पोस्ट करने की सलाह देता हूं और हमने इसका परीक्षण किया है। मैं इस समस्या के समाधान समाधान के बिना अन्य परियोजनाओं के साथ आगे बढ़ गया हूं, लेकिन मैं अभी भी समाधान के बारे में उत्सुक हूं। – josephus

1

मैंने मीडियाप्लेयर पर वीडियो प्लेबैक के साथ ऐसा नहीं किया है, लेकिन जब मैंने स्ट्रीम को बाधित कर दिया है तो मैंने ऑडियो फ़ाइलों के साथ कुछ ऐसा किया है क्योंकि उपयोगकर्ता ने 3 जी से वाईफ़ाई तक स्विच किया है।

मुझे लगता है कि आप जो देरी देख रहे हैं वह है कि मीडिया प्लेयर इनपुट फ़ाइल को बफर कर रहा है। तो हो सकता है कि आप शुरुआत में दोनों खिलाड़ियों को परिभाषित कर सकें? आपको डेटासोर्स को परिभाषित करना चाहिए और दोनों खिलाड़ियों को तैयार करना चाहिए, लेकिन उनमें से केवल एक ही शुरू करना चाहिए।

फिर आपके ऑनमिशन लिस्टर में आप मौजूदा को रीसेट करने और एक नया डेटास्रोत स्थापित करने के बजाय उन्हें फ़्लिप कर सकते हैं।

player.release(); 
    player = flipPlayer; 
    flipPlayer = null; 
    player.start(); 

जाहिर है या तो आप flipPlayer के लिए एक अलग onPreparedListener का उपयोग करें या player.start() ले onPrepare से बाहर करना होगा। (चूंकि आप इसे समकालिक रूप से बुला रहे हैं, मैंने सोचा नहीं होगा कि यह एक मुद्दा था)।

+0

हम्म के लिए मेडिपैप्लेयर को एक बड़ा अंगूठा देता हूं। एक कोशिश लायक़। हालांकि रिलीज नहीं होगा() वास्तव में वहां एक खाली स्क्रीन छोड़ दें? – josephus

1

मुझे नहीं लगता कि यह संभव है।

कारण: मॉर्टप्लेयर विंडोज मोबाइल के लिए भी उपलब्ध था और इसकी ताकत में से एक यह था कि यह अंतहीन खेल का समर्थन करता था।हालांकि यह ऐप्लिकेशन का Android संस्करण में नहीं है, और डेवलपर खुद लिखता है कि एसडीके XDA पर यह अनुमति नहीं देता: http://forum.xda-developers.com/showpost.php?p=5364530&postcount=5

HTH, डेनियल

0

आप तैयार करने के लिए प्रयास किया था (खोला/तैयार) 2 वीडियो व्यू, एक दिखाई देने वाला, अन्य अदृश्य और बंद कर दिया गया है, और जल्द ही आपको ऑनकंपलिशन लिस्टनर कॉलबैक मिल गया है, दूसरा दृश्यमान बनाएं, इसे शुरू करें, और पहले एक को छुपाएं। इस बीच, दूसरे एक नाटक के रूप में, आप दूसरी वीडियो खोलने/तैयार करने के लिए 1 वीडियो व्यू पर खुले/तैयार कर सकते हैं।

+0

ऑन कॉम्प्लेशन लिस्टर को पहले वीडियो खत्म होने के ठीक बाद बुलाया जाएगा। गैप वहां से शुरू होगा, और दूसरा खेलना शुरू करने के बाद समाप्त होगा (निश्चित रूप से दृश्यता बदलने के बाद)। काम नहीं करेगा – josephus

4

मैं भी एक ही समस्या के रूप में लिंक

VideoView Disappears for a second when video is changed

नीचे द्वारा उल्लिखित लेकिन इस मुद्दे अभ्यस्त होते हैं यदि आप Android 4.0+ (आईसीएस) का उपयोग कर प्रयास करें। मैंने 4.0 से अपने ऐप में VideoView.java और MediaPlayer.java पोर्ट करना शुरू किया, लेकिन यह अब तक जटिल और कोई भाग्य नहीं लगता है। असल में यह पुराने संस्करणों के देशी कोड में एक बग लगता है।

0

@ user1263019 - क्या आप अपने ऐप पर एंड्रॉइड 4.0 मीडियाप्लेयर पोर्ट करने में सक्षम थे? मुझे एक ही समस्या का सामना करना पड़ रहा है और मैं एक अच्छा समाधान ढूंढ रहा हूं। मेरे मामले में SurfaceView पर एक छवि है जिसमें वीडियो खेलने के लिए छुपाया जाना चाहिए, लेकिन कॉलिंग प्रारंभ() और वीडियो की वास्तविक शुरुआत के बीच एक अंतर है। एकमात्र समाधान अब तक एक धागा अगर getCurrentPosition()> 0.

विषय पर है की जाँच करता है कि शुरू करने के लिए है - मुझे लगता है कि इसमें लगातार प्लेबैक के लिए, हालांकि इस तरह के क्षमता है करने के लिए Winamp दावा संभव नहीं है। एक गंदे हैक दूसरे खिलाड़ी को प्लेबैक के अंत से पहले कई सेकंड तैयार करना है और फिर प्लेबैक के अंत से पहले दूसरे खिलाड़ी 100-200ms के प्रारंभ() को कॉल करना है।

0

अपने exoplayer कार्यान्वयन (या मीडियाप्लेयर) एक हैंडलर का उपयोग बार बार, एक runnable पोस्ट करने के लिए खेलते समय, कि वर्तमान ट्रैकिंग समय हो जाता है और एक कॉलबैक को पास कर देता में:

public interface MediaAction { 
    public void onTrackingChanged(long currentPosition); 
} 

public class ExoPlayerImplementation implements Exoplayer { 

    .. 

    private MediaAction mediaActionCallback; 
    public void setMediaActionCallback(MediaAction ma) { 
    mediaActionCallback = ma; 
    } 
    public void releaseMediaAction() { mediaActionCallback = null; } 

    private Handler trackingCallback = new Handler(Looper.getMainLooper()); 

    Runnable trackingTask; 
    private Runnable getTrackingTask() { 
    Runnable r = new Runnable { 
     @Override public void run() { 
     long currentPosition = getCurrentPosition(); 
     if (mediaActionCallback != null) { 
      mediaActionCallback.onTrackingChanged(currentPosition); 
     } 
     // 60hz is 16 ms frame delay... 
     trackingCallback.postDelayed(getTrackingTask(), 15); 
     } 
    }; 
    trackingTask = r; 
    return r; 
    } 

    public void play() { 
    // exoplayer start code 
    trackingCallback.post(getTrackingTask()); 
    } 

    public void pause/stop() { 
    trackingCallback.removeCallbacks(trackingTask); 
    } 

    .. 

} 

और अब आप जब ट्रैक कर सकते हैं वर्तमान स्थिति वास्तव में बदल गई है - यदि यह बदल गया है, तो आप अपने वीडियो आउटपुट व्यू/स्वैप दृश्य/पूर्वावलोकन को हटा सकते हैं (यानी, प्रारंभिक फ्रेम को पकड़ने के लिए मीडिया एक्स्ट्रेक्टर का उपयोग करें, एक छवि दृश्य में पूर्वावलोकन के रूप में ओवरले करें, फिर एक बार वर्तमान स्थिति बढ़ रही है)। आप इस कोड को राज्य श्रोता के साथ संयोजित करके अधिक पूर्ण कर सकते हैं: फिर आप जानते हैं कि आप बफरिंग कर रहे हैं (वर्तमान स्थिति बनाम बफरिंग स्थिति देखें), वास्तव में उचित कॉलबैक (मीडियाएक्शन में) के साथ खेलना, रोका या बंद कर दिया गया है। आप इस विधि को MediaPlayer और ExoPlayer क्लास दोनों पर लागू कर सकते हैं (क्योंकि यह केवल एक इंटरफ़ेस और हैंडलर है)।

आशा है कि मदद करता है!

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