2012-11-28 35 views
15

मैं एक VideoView जो इस तरह की स्थापना की है के लिए:VideoView माता पिता ऊंचाई से मेल खाते हैं और पहलू अनुपात रखने

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/player" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 

    <VideoView 
     android:id="@+id/video" 
     android:layout_width="wrap_content" 
     android:layout_height="match_parent" 
     android:layout_centerInParent="true" 
     android:layout_centerVertical="true" /> 

    <ProgressBar 
     android:id="@+id/loader" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerHorizontal="true" 
     android:layout_centerVertical="true" /> 

</RelativeLayout> 

लेकिन VideoView के अनुसार माता पिता कंटेनर की चौड़ाई से मेल खाता है, और फिर ऊंचाई सेट कर दिया जाता भारित फिल्म के पहलू अनुपात।
मैं सिर्फ विपरीत करना चाहता हूं, मैं चाहता हूं कि वीडियो व्यू माता-पिता की ऊंचाई से मेल खाए, जबकि पहलू अनुपात को बरकरार रखा जाए, वीडियो पक्षों पर फिसल जाएगा।

मैं पैरेंट को भरने के लिए वीडियो व्यू को खींचने में कामयाब रहा लेकिन फिर पहलू अनुपात नहीं रखा गया।

एक और बात है, मैं इस तरह VideoView को MediaController जोड़ रहा:

MediaController controllers = new MediaController(this) { 
    @Override 
    public void hide() { 
     if (state != State.Hidden) { 
      this.show(); 
     } 
     else { 
      super.hide(); 
     } 
    } 
}; 
controllers.setAnchorView(videoView); 
videoView.setMediaController(controllers); 

videoView.setOnPreparedListener(new OnPreparedListener() { 
    @Override 
    public void onPrepared(MediaPlayer mediaPlayer) { 
     controllers.show(); 
    } 
}); 

यह महान काम करता है, और नियंत्रकों हमेशा पर रहने के लिए, लेकिन नियंत्रकों की ऊंचाई खाते जब में नहीं लिया जा रहा है यह गणना करना कि वीडियो कहां रखना है (क्योंकि यह लंबवत केंद्रित है)।

मेरे दो सवाल तो कर रहे हैं:

  1. मैं कैसे VideoView माता पिता की ऊंचाई से मेल खाते हैं अभी तक पहलू अनुपात रखना कर सकता हूँ?
  2. मैं वीडियोव्यू को अपने नियंत्रकों की ऊंचाई को कैसे ध्यान में रखूं?

धन्यवाद।

+0

क्या आप किसी वेबव्यू या वीडियो व्यू के बारे में बात कर रहे हैं? आप लगभग आधा रास्ता बदलते हैं। –

उत्तर

16

आपको अंतर्निहित वीडियो व्यू से विस्तारित होना चाहिए।

वीडियो दृश्य से पहले setVideoSize पर कॉल करें, तो आप वीडियो से निकाले गए थंबनेल से वीडियो आकार प्राप्त कर सकते हैं।

तो है कि, जब वीडियो को देखे जाने के onMeasure कहा जाता है, दोनों mVideoWidth & mVideoHeight हैं> 0.

आप खाते में नियंत्रकों की ऊंचाई चाहते हैं, आप इसे खुद onMeasure विधि में कर सकते हैं।

आशा मदद करेगा।

public class MyVideoView extends VideoView { 

     private int mVideoWidth; 
     private int mVideoHeight; 

     public MyVideoView(Context context, AttributeSet attrs) { 
      super(context, attrs); 
     } 

     public MyVideoView(Context context, AttributeSet attrs, int defStyle) { 
      super(context, attrs, defStyle); 
     } 

     public MyVideoView(Context context) { 
      super(context); 
     } 

     public void setVideoSize(int width, int height) { 
      mVideoWidth = width; 
      mVideoHeight = height; 
     } 

     @Override 
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
      // Log.i("@@@", "onMeasure"); 
      int width = getDefaultSize(mVideoWidth, widthMeasureSpec); 
      int height = getDefaultSize(mVideoHeight, heightMeasureSpec); 
      if (mVideoWidth > 0 && mVideoHeight > 0) { 
       if (mVideoWidth * height > width * mVideoHeight) { 
        // Log.i("@@@", "image too tall, correcting"); 
        height = width * mVideoHeight/mVideoWidth; 
       } else if (mVideoWidth * height < width * mVideoHeight) { 
        // Log.i("@@@", "image too wide, correcting"); 
        width = height * mVideoWidth/mVideoHeight; 
       } else { 
        // Log.i("@@@", "aspect ratio is correct: " + 
        // width+"/"+height+"="+ 
        // mVideoWidth+"/"+mVideoHeight); 
       } 
      } 
      // Log.i("@@@", "setting size: " + width + 'x' + height); 
      setMeasuredDimension(width, height); 
     } 
} 
+1

यह निश्चित रूप से मदद की लेकिन मैं यह भी यहाँ के रूप में स्क्रीन से बड़े होने देखें स्थापित करने के लिए की जरूरत: http://stackoverflow.com/questions/3813049/how-to-create-a-view-that-is-bigger- स्क्रीन से – Kibi

+0

@ ax003d मैंने इस वीडियो को देखा है View.setLayoutParams (पैरा); videoView.setDimensions (params.width, params.width); videoView.getHolder()। SetFixedSize (params.width, params.height); लेकिन अभी भी अपनी मेरी videoview ऊंचाई – Erum

+3

की स्थापना नहीं यह अच्छा जवाब है, लेकिन इसे मैन्युअल के बजाय setVideoSize() का उपयोग, मैं विधि ओवरराइड होगा जो लोड वीडियो: @Override सार्वजनिक शून्य setVideoURI (उरी uri) { MediaMetadataRetriever रिट्रीवर = नए MediaMetadataRetriever (); retriever.setDataSource (this.getContext(), uri); mVideoWidth = Integer.parseInt (retriever.extractMetadata (MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)); mVideoHeight = Integer.parseInt (retriever.extractMetadata (MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)); super.setVideoURI (uri); } – Arthez

3

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

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/relative_parent" 
    android:background="#000000"> 
    <VideoView 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentRight="true" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_centerInParent="true" 
     android:focusable="false" 
     android:focusableInTouchMode="false" 
     android:id="@+id/videoView" /> 
</RelativeLayout> 
0

मैं इंटरनेट पर इसे खोजने पर समय बिताता हूं मुझे कोई बेहतर समाधान नहीं मिला जो डिफ़ॉल्ट वीडियो दृश्य पर लागू हो सकता है। इसलिए मैं पुस्तकालयों जो मेरी आवश्यकता का समाधान होगा के लिए खोज अंत में मैं एक 'FullscreenVideoView' (https://github.com/rtoshiro/FullscreenVideoView) इस हल मेरी आवश्यकता पाया

3
public class MyVideoView extends VideoView { 
    private int mVideoWidth; 
    private int mVideoHeight; 

    public MyVideoView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public MyVideoView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    public MyVideoView(Context context) { 
     super(context); 
    } 


    @Override 
    public void setVideoURI(Uri uri) { 
     MediaMetadataRetriever retriever = new MediaMetadataRetriever(); 
     retriever.setDataSource(this.getContext(), uri); 
     mVideoWidth = Integer.parseInt(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)); 
     mVideoHeight = Integer.parseInt(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)); 
     super.setVideoURI(uri); 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     // Log.i("@@@", "onMeasure"); 
     int width = getDefaultSize(mVideoWidth, widthMeasureSpec); 
     int height = getDefaultSize(mVideoHeight, heightMeasureSpec); 
     if (mVideoWidth > 0 && mVideoHeight > 0) { 
      if (mVideoWidth * height > width * mVideoHeight) { 
       // Log.i("@@@", "image too tall, correcting"); 
       height = width * mVideoHeight/mVideoWidth; 
      } else if (mVideoWidth * height < width * mVideoHeight) { 
       // Log.i("@@@", "image too wide, correcting"); 
       width = height * mVideoWidth/mVideoHeight; 
      } else { 
       // Log.i("@@@", "aspect ratio is correct: " + 
       // width+"/"+height+"="+ 
       // mVideoWidth+"/"+mVideoHeight); 
      } 
     } 
     // Log.i("@@@", "setting size: " + width + 'x' + height); 
     setMeasuredDimension(width, height); 
    } 
} 
+1

इस कोड के लिए बहुत बहुत धन्यवाद। यह काम करता हैं। – Smeet

+0

गैलेक्सी एस 3 – Slava

+1

पर काम नहीं करता है Nexus 5X पर भी काम नहीं करता है :( – Slava

2

प्रश्न 1 के बारे में, मैं हैरान कोई भी MediaPlayer के स्केलिंग मोड का संभावित उपयोग उल्लेख किया है हूँ । https://developer.android.com/reference/android/media/MediaPlayer.html#setVideoScalingMode(int)

इसमें 2 मोड हैं। वे दोनों हमेशा दृश्य क्षेत्र भरते हैं।पक्ष अनुपात को संरक्षित करते समय अंतरिक्ष को भरने के लिए, इस प्रकार लंबी तरफ फसल, आपको दूसरे मोड, VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING पर स्विच करने की आवश्यकता है। यह समस्या का एक हिस्सा हल करता है। दूसरा हिस्सा वीडियो व्यू के मापने वाले व्यवहार को बदलना है, जैसे कि कुछ अन्य उत्तरों का प्रदर्शन होता है। इस तरह मैंने इसे किया, ज्यादातर आलस्य से बाहर और मेटाडेटा एपीआई से परिचित नहीं है जो दूसरों का उपयोग करते हैं, आप इस विधि का उपयोग करने के लिए स्वागत करते हैं या दृश्य के आकार को ठीक करने के लिए अन्य तरीकों में से एक का स्वागत करते हैं। कंबल पकड़ सुरक्षा सुनिश्चित करता है जब इसे mMediaPlayer मौजूद होने से पहले कहा जाता है, क्योंकि इसे कई बार कहा जा सकता है, और पुराने व्यवहार पर भी वापस आ जाता है, फ़ील्ड का नाम कभी भी बदलना चाहिए।

class FixedSizeVideoView : VideoView { 
    constructor(ctx: Context) : super(ctx) 
    constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs) 

    // rather than shrink down to fit, stay at the size requested by layout params. Let the scaling mode 
    // of the media player shine through. If the scaling mode on the media player is set to the one 
    // with cropping, you can make a player similar to AVLayerVideoGravityResizeAspectFill on iOS 
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 
     try { 
      val mpField = VideoView::class.java.getDeclaredField("mMediaPlayer") 
      mpField.isAccessible = true 
      val mediaPlayer: MediaPlayer = mpField.get(this) as MediaPlayer 

      val width = View.getDefaultSize(mediaPlayer.videoWidth, widthMeasureSpec) 
      val height = View.getDefaultSize(mediaPlayer.videoHeight, heightMeasureSpec) 
      setMeasuredDimension(width, height) 
     } 
     catch (ex: Exception) { 
      super.onMeasure(widthMeasureSpec, heightMeasureSpec) 
     } 
    } 
} 

तो लेआउट में इस कक्षा का उपयोग करके, आप जहां भी मौका रखते हैं, मीडिया प्लेयर पर स्केलिंग मोड को बदल दें। जैसे:

 video.setOnPreparedListener { mp: MediaPlayer -> 
      mp.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING) 
      mp.isLooping = true 
      mp.setScreenOnWhilePlaying(false) 
     } 
     video.start() 
+0

यह एंड्रॉइड नहीं है? – jobbert

+1

कोटलिन, प्रिय महोदय :) – user3175580

0

मैं समाधान का एक बहुत कोशिश की है, मेरे वीडियो 1000 * 1000 प्रारूप में हमेशा था, जबकि, इसलिए मैं जो लोग अपने पहलू अनुपात पता लिए एक आसान समाधान बना लिया है। इससे पहले कि आप लोड वीडियो ऊंचाई बदल सकते हैं और प्रोग्राम के रूप में इस तरह के साथ

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/video_holder" 
     android:layout_width="wrap_content" 
     android:layout_height="fill_parent" 
     android:clipToPadding="false"> 

     <VideoView 
      android:id="@+id/videoView" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:layout_alignParentBottom="true" 
      android:layout_alignParentEnd="true" 
      android:layout_alignParentStart="true" 
      android:layout_alignParentTop="true" /> 
</RelativeLayout> 

तब:: 1 आकार अनुपात के:

int i = videoView.getHeight() > videoView.getWidth() ? videoView.getHeight() : videoView.getWidth(); 
    video_holder.setLayoutParams(new ConstraintLayout.LayoutParams(i, i)); 
बेशक

यह केवल 1 के साथ काम करता पहले इस तरह की एक RelativeLayout में एक VideoView बनाने लेकिन आप ऊंचाई या चौड़ाई को बदलने के लिए बस अपने पहलू अनुपात का उपयोग कर सकते हैं।