2010-09-10 14 views
49

Mam VideoView, który zajmuje górną połowę aktywności w orientacji pionowej z dolną połową ekranu pokazującą niektóre obrazy i tekst. Odtwarzam strumień wideo rtsp w widoku wideo po rozpoczęciu działania. Mam załączeniu MediaController do VideoView za pomocą następującego kodu:Pozycjonowanie MediaController przez VideoView

MediaController controller = new MediaController(this); 
    controller.setAnchorView(this.videoView); 
    controller.setMediaPlayer(this.videoView); 
    this.videoView.setMediaController(controller); 

Kiedy dotknij VideoView aby przywołać MediaController na ekranie spodziewałem sterowania odtwarzaniem pojawiać nakładanie dolny obszar VideoView (dno MediaController nawet z dolnej części VideoView). Zamiast tego MediaController wyświetla się niżej na dole, nakładając część grafiki i tekstu, które mam pod VideoView.

Czy są jakieś dodatkowe kroki, które należy podjąć, aby MediaController pojawił się tam, gdzie chcę na ekranie?

+6

Jestem zainteresowany tym, jak dobrze. Czy kiedykolwiek to rozgryzłeś? – Ronnie

+1

Nie, nigdy tego nie zrobiłem. –

+1

Spójrz na to pytanie http://stackoverflow.com/questions/6093756/how-to-re-position-mediacontroller – Sandeep

Odpowiedz

5

Szczerze mówiąc, po prostu napiszę własnego kontrolera. W rzeczywistości I did once.

Powiedziawszy to, spróbuj setAnchorView() - po przeczytaniu kodu źródłowego, MediaController pojawi się na dole każdego widoku zakotwiczenia.

+3

Jestem zdesperowany, aby dowiedzieć się Wczoraj napisałem pytanie o rozszerzenie MediaController: http://stackoverflow.com/questions/7881272/extending-mediacontroller-for-android .Patrzałem na twój kod github, ale nie mogłem go rozgryźć Myślę, że muszę przesłonić metodę setAnchorView, aby móc umieścić MediaController w dowolnym miejscu. Czy jest to sposób na "unoszenie się" i ustawianie go w ten sposób? – Ronnie

+0

Chcę dodać naklejki do wideo, opublikowałem szczegółowe pytanie http://stackoverflow.com/questions/43963522/android-stickers-on-video-using-ffmpeg, moim problemem jest uzyskanie danych wprowadzonych przez użytkownika, jak określił to commonsware, w stosunku do obrazu nakładki (pozycja, skala , obrót) i tło wideo – 1234567

7

Używam tego kodu, aby go rozwiązać.

mediaController.setPadding(0, 0, 0, px); 

aby ustawić widok mediacontroller na żądaną pozycję. Mam nadzieję, że to ci pomoże.

+3

Co to jest 'px' ....? –

+1

px to zmienna typu int, która jest liczbą pikseli od dołu ekranu. – Rongan

+1

Dokładnie tego, czego szukałem. – nifo

40

Ustawienie widoku zakotwiczenia działa tylko wtedy, gdy znany jest rozmiar wideo - będzie to , a nie po inicjacji. Ale można zrobić coś takiego:

video.setOnPreparedListener(new OnPreparedListener() { 
     @Override 
     public void onPrepared(MediaPlayer mp) { 
      mp.setOnVideoSizeChangedListener(new OnVideoSizeChangedListener() { 
      @Override 
      public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { 
       /* 
       * add media controller 
       */ 
       mc = new MediaController(YourActivity.this); 
       video.setMediaController(mc); 
       /* 
       * and set its position on screen 
       */ 
       mc.setAnchorView(video); 
      } 
     }); 
    } 
}); 
+0

ma sens wywołanie metody setAnchorView() po wyświetleniu gotowości do uruchomienia. tj. wywołanie z onPrepared() – CoDe

+5

setAnchorView (wideo) wykorzystuje nadrzędny element VideoView do nałożenia elementów sterowania multimediami. Jeśli masz film o stałej wysokości, umieść go wewnątrz frarmayout, aby elementy sterujące multimediami znajdowały się na górze wideo. – Prakash

+0

@Prakash To jest to, czego szukałem .. Twój komentarz był wszystkim, czego potrzebowałem ... Wielkie dzięki. –

11

I napotkać ten sam problem niedawno, używając setAnchorView (videoView) będzie ustawić regulator w pełni pod VideoView zamiast unosić się na dolnej powierzchni niego. Mój VideoView to trzeci ekran w górnym obszarze, więc kontroler kończy się na tym, co obejrzy View w VideoView.

Poniżej jest droga ja w końcu robi to bez pisania pełnowymiarową niestandardowego sterownika (tylko nadrzędnymi onSizeChanged z MediaController przenieść kotwica w górę):

Zastosowanie FrameLayout jako kotwica dla MediaContoller, owinąć go wraz z VideoView jak poniżej:

<RelativeLayout 
    android:id="@+id/videoLayout" 
    android:layout_width="match_parent" 
    android:layout_height="0dp" 
    android:layout_weight="1.3" 
    android:layout_gravity="center" 
    android:background="#000000"> 

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

    <FrameLayout android:id="@+id/controllerAnchor" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentRight="true" 
     /> 

</RelativeLayout> 

Tworzenie niestandardowego MediaController które będą poruszać FrameLayout górę (z MediaController który jest przymocowany do niego pójdą), gdy jego wielkość zmiany:

public class MyMediaController extends MediaController 
{ 
    private FrameLayout anchorView; 


    public MyMediaController(Context context, FrameLayout anchorView) 
    { 
     super(context); 
     this.anchorView = anchorView;  
    } 

    @Override 
    protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld) 
    { 
     super.onSizeChanged(xNew, yNew, xOld, yOld); 

     RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) anchorView.getLayoutParams(); 
     lp.setMargins(0, 0, 0, yNew); 

     anchorView.setLayoutParams(lp); 
     anchorView.requestLayout(); 
    }  
} 

Użyj przycisku sterowania niestandardowe powyżej w miejsce standardowego, a następnie umieścić go na FrameLayout:

protected void onCreate(Bundle savedInstanceState) 
{ 

    //... 

    videoView = (VideoView) findViewById(R.id.videoView1);  
    videoController = new MyMediaController(this, (FrameLayout) findViewById(R.id.controllerAnchor));    
    videoView.setMediaController(videoController);  

    //...  
} 

public void onPrepared(MediaPlayer mp) 
{ 
    videoView.start();    

    FrameLayout controllerAnchor = (FrameLayout) findViewById(R.id.controllerAnchor); 
    videoController.setAnchorView(controllerAnchor);     
} 
+0

Jego prefekt dzięki. – Steve

15

znalazłem bardzo proste rozwiązanie.

Wystarczy owinąć videoView w FrameLayout następnie można dodać MediaController tej FrameLayout z kodu, takich jak to:

MediaController mc = new MediaController(context); 
    videoView.setMediaController(mc); 

    FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); 
    lp.gravity = Gravity.BOTTOM; 
    mc.setLayoutParams(lp); 

    ((ViewGroup) mc.getParent()).removeView(mc); 

    ((FrameLayout) findViewById(R.id.videoViewWrapper)).addView(mc); 

EDIT: od kiedy pisał tę odpowiedź wpadłem na wiele spraw z coraz to ukryć i kontrolowanie jego rozmiar tak co skończyło się robi ja tylko tworzę własny układ z kontroli, że mogę ożywionej i pracuję bez głowy

+0

najlepsze rozwiązanie, dzięki – keybee

+0

Działa jak urok! Dziękuję Ci! –

+0

doskonale działał. Oszczedziłem wiele wysiłku :) – Radhey

3
//It work good with me 

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" > 

    <VideoView 
     android:id="@+id/videoview" 
     android:layout_width="640dp" 
     android:layout_height="400dp" 
     android:layout_centerInParent="true" > 
    </VideoView> 

     <FrameLayout 
      android:id="@+id/videoViewWrapper" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_alignParentBottom="true" > 
     </FrameLayout> 

    </RelativeLayout> 

package com.example.videoview; 

import android.app.Activity; 
import android.content.res.Configuration; 
import android.media.MediaPlayer; 
import android.media.MediaPlayer.OnCompletionListener; 
import android.media.MediaPlayer.OnPreparedListener; 
import android.media.MediaPlayer.OnVideoSizeChangedListener; 
import android.os.Bundle; 
import android.os.Handler; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnTouchListener; 
import android.view.ViewGroup; 
import android.widget.FrameLayout; 
import android.widget.MediaController; 
import android.widget.RelativeLayout; 
import android.widget.RelativeLayout.LayoutParams; 
import android.widget.Toast; 
import android.widget.VideoView; 

public class MainActivity extends Activity { 

    // private String path = "http://clips.vorwaerts-gmbh.de/VfE_html5.mp4"; 
    private String path = "http://2387227f13276d2e8940-fbe0b8d9df729a57ca0a851a69d15ebb.r55.cf1.rackcdn.com/hero_2012_demo.mp4"; 

    private VideoView mVideoView; 

    MediaController mc; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     if (mVideoView != null) 
      return; 
     /** 
     * TODO: Set the path variable to a streaming video URL or a local media 
     * file path. 
     */ 

     mVideoView = (VideoView) findViewById(R.id.videoview); 
     mVideoView.setOnCompletionListener(new OnCompletionListener() { 

      @Override 
      public void onCompletion(MediaPlayer mp) { 
       Toast.makeText(MainActivity.this, "The End", Toast.LENGTH_LONG) 
         .show(); 
      } 
     }); 

     if (path == "") { 
      // Tell the user to provide a media file URL/path. 
      Toast.makeText(
        MainActivity.this, 
        "Please edit MainActivity, and set path" 
          + " variable to your media file URL/path", 
        Toast.LENGTH_LONG).show(); 

     } else { 
      /* 
      * Alternatively,for streaming media you can use 
      * mVideoView.setVideoURI(Uri.parse(path)); 
      */ 
      mVideoView.setVideoPath(path); 

      mVideoView 
        .setMediaController(new MediaController(MainActivity.this)); 
      mVideoView.requestFocus(); 

      mVideoView.setOnPreparedListener(new OnPreparedListener() { 

       @Override 
       public void onPrepared(MediaPlayer mp) { 
        // TODO Auto-generated method stub 
        mp.setOnVideoSizeChangedListener(new OnVideoSizeChangedListener() { 
         @Override 
         public void onVideoSizeChanged(MediaPlayer mp, 
           int width, int height) { 
          /* 
          * add media controller 
          */ 
          mc = new MediaController(MainActivity.this); 
          mVideoView.setMediaController(mc); 
          /* 
          * and set its position on screen 
          */ 
          mc.setAnchorView(mVideoView); 

          ((ViewGroup) mc.getParent()).removeView(mc); 

          ((FrameLayout) findViewById(R.id.videoViewWrapper)) 
            .addView(mc); 
          mc.setVisibility(View.INVISIBLE); 
         } 
        }); 
        mVideoView.start(); 
       } 
      }); 

      mVideoView.setOnTouchListener(new OnTouchListener() { 

       @Override 
       public boolean onTouch(View v, MotionEvent event) { 
        // TODO Auto-generated method stub 
        if (mc != null) { 
         mc.setVisibility(View.VISIBLE); 
         new Handler().postDelayed(new Runnable() { 

          @Override 
          public void run() { 
           mc.setVisibility(View.INVISIBLE); 
          } 
         }, 2000); 
        } 

        return false; 
       } 
      }); 

     } 
    } 

    private RelativeLayout.LayoutParams paramsNotFullscreen, paramsFullscreen; 

    /** 
    * handle with the configChanges attribute in your manifest 
    */ 
    @Override 
    public void onConfigurationChanged(Configuration newConfig) { 
     // TODO Auto-generated method stub 
     super.onConfigurationChanged(newConfig); 

     if (paramsFullscreen == null) { 
      paramsNotFullscreen = (RelativeLayout.LayoutParams) mVideoView 
        .getLayoutParams(); 
      paramsFullscreen = new LayoutParams(paramsNotFullscreen); 
      paramsFullscreen.setMargins(0, 0, 0, 0); 
      paramsFullscreen.height = ViewGroup.LayoutParams.MATCH_PARENT; 
      paramsFullscreen.width = ViewGroup.LayoutParams.MATCH_PARENT; 
      paramsFullscreen.addRule(RelativeLayout.CENTER_IN_PARENT); 
      paramsFullscreen.addRule(RelativeLayout.ALIGN_PARENT_LEFT); 
      paramsFullscreen.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); 
      paramsFullscreen.addRule(RelativeLayout.ALIGN_PARENT_TOP); 
      paramsFullscreen.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); 
     } 
     // To fullscreen 
     if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { 
      mVideoView.setLayoutParams(paramsFullscreen); 

     } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { 
      mVideoView.setLayoutParams(paramsNotFullscreen); 
     } 
    } 

    @Override 
    protected void onPause() { 
     if (mVideoView.isPlaying()) { 
      mVideoView.pause(); 
     } 
     super.onPause(); 
    } 

    @Override 
    public void onBackPressed() { 
     if (mVideoView != null) { 
      mVideoView.stopPlayback(); 
     } 
     finish(); 
    } 
} 


<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.videoview" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk 
     android:minSdkVersion="8" 
     android:targetSdkVersion="17" /> 

    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <activity 
      android:name="com.example.videoview.MainActivity" 
      android:configChanges="orientation|screenSize" 
      android:label="@string/app_name" 
      android:theme="@android:style/Theme.Dialog" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 
+1

Proszę dać mi znać, jeśli masz jakieś problemy –

+0

nie ma problemu, kod działa dobrze –

0

jest to pierwszy raz, gdy odpowiedź na pytanie w stackoverflow, Wrzucam tylko wideo Zobacz wewnątrz FrameLayout z tymi samymi środkami. MediaController będzie na dole FrameLayout. Ten pracował dla mnie:

main_activity.XML:

  <FrameLayout  
      android:id="@+id/frame_layout_video" 
      android:layout_centerHorizontal="true" 
      android:layout_width="wrap_content" 
      android:layout_height="400dp"> 

      <VideoView 
       android:id="@+id/video_select" 
       android:layout_width="wrap_content" 
       android:layout_height="400dp" 
       android:adjustViewBounds="true" 
       android:clickable="true" 
       android:scaleType="centerCrop" 
       /> 

     </FrameLayout> 

MainActivity.java:

@Override 
public void onClick(View v) { 
    int i = v.getId(); 

    if(i == R.id.select_video){ 
     selectVideo(); 
    } 

private void selectVideo(){ 
    //this code is to get videos from gallery: 
    Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT); 
    galleryIntent.addCategory(Intent.CATEGORY_OPENABLE); 
    galleryIntent.setAction(Intent.ACTION_GET_CONTENT); 
    galleryIntent.setType("video/*"); 
    startActivityForResult(galleryIntent, GALLERY_REQUEST); 

    MediaController mediaController = new MediaController(this); 
    mediaController.setAnchorView(mVideo); 
    //mVideo is the VideoView where I insert the video 
    mVideo.setMediaController(mediaController); 
    mVideo.pause(); 
} 


@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 

    switch (requestCode) { 
     case 1: 
      if (resultCode == RESULT_OK) { 
       mVideoUri = data.getData(); 
       mVideo.setVideoURI(mVideoUri); 
       mVideo.start(); 
      } 
    } 
} 
Powiązane problemy