title: Playing video using textureview in recyclerview
body: <p>I am trying to implement a list with videos like vine or Instagram app. Where they play video plays when list item is shown or fully visible and video pauses when list item gets hided. I am using textureview with media player to play a video from url and added it as list item in recyclerview. Following is my code.</p>
  
  <p>VideosAdapter Class:</p>
  
  <pre><code>public class VideosAdapter extends RecyclerView.Adapter&lt;VideosAdapter.ViewHolder&gt; {
  
  Context context;
  private ArrayList&lt;String&gt; urls;
  
  public static class ViewHolder extends RecyclerView.ViewHolder {
  
      public LinearLayout layout;
      public TextView textView;
  
      public ViewHolder(View v) {
          super(v);
          layout = (LinearLayout) v.findViewById(R.id.linearLayout);
          textView = (TextView) v.findViewById(R.id.textView);
      }
  }
  
  public VideosAdapter(Context context, ArrayList&lt;String&gt; urls) {
      this.context = context;
      this.urls = urls;
  }
  
  // Create new views (invoked by the layout manager)
  @Override
  public VideosAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
      // create a new view
      View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_main, parent, false);
      ViewHolder viewHolder = new ViewHolder(v);
      return viewHolder;
  }
  
  // Replace the contents of a view (invoked by the layout manager)
  @Override
  public void onBindViewHolder(ViewHolder holder, int position) {
  
      String url = urls.get(position);
      holder.textView.setText(url);
      playVideo(holder, url);
  }
  
  @Override
  public int getItemCount() {
      return urls.size();
  }
  
  private void playVideo(ViewHolder holder, String url)
  {
      final CustomVideoPlayer vid = new CustomVideoPlayer(String.valueOf(url), context);
      holder.layout.addView(vid);
      holder.layout.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
  
              vid.changePlayState();
          }
      });
  }
  }
  </code></pre>
  
  <p>CustomVideoPlayer Class:</p>
  
  <pre><code>public class CustomVideoPlayer extends  TextureView implements TextureView.SurfaceTextureListener
  {
  
  Context context;
  String url;
  MediaPlayer mp;
  Surface surface;
  SurfaceTexture s;
  
  public CustomVideoPlayer(Context context, AttributeSet attrs)
  {
      super(context, attrs);
      this.context = context;
  }
  
  public CustomVideoPlayer(String ur, Context context)
  {
      super(context);
      this.setSurfaceTextureListener(this);
      this.url = ur;
      this.context = context;
  
  }
  
  @Override
  public void onSurfaceTextureAvailable(final SurfaceTexture surface, int arg1, int arg2) {
  
      this.s = surface;
      Log.d("url", this.url);
      startVideo(surface);
  }
  @Override
  public boolean onSurfaceTextureDestroyed(SurfaceTexture arg0) {
  
      return true;
  }
  @Override
  public void onSurfaceTextureSizeChanged(SurfaceTexture arg0, int arg1,int arg2) {
  }
  @Override
  public void onSurfaceTextureUpdated(SurfaceTexture arg0) {
  }
  
  public void setVideo(String url)
  {
      this.url = url;
  }
  
  public void startVideo(SurfaceTexture t)
  {
      this.surface = new Surface(t);
      this.mp = new MediaPlayer();
      this.mp.setSurface(this.surface);
      try {
          Uri uri = Uri.parse(this.url);
          this.mp.setDataSource(url);
          this.mp.prepareAsync();
  
          this.mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
              public void onPrepared(MediaPlayer mp) {
  
                  mp.setLooping(true);
                  mp.start();
  
              }
          });
      } catch (IllegalArgumentException e1) {
          e1.printStackTrace();
      } catch (SecurityException e1) {
          e1.printStackTrace();
      } catch (IllegalStateException e1) {
          e1.printStackTrace();
      } catch (IOException e1) {
          e1.printStackTrace();
      }
      try {
  
      } catch (IllegalArgumentException e) {
          e.printStackTrace();
      } catch (SecurityException e) {
          e.printStackTrace();
      } catch (IllegalStateException e) {
          e.printStackTrace();
      }
      try {
  
      } catch (IllegalStateException e) {
          e.printStackTrace();
      }
  
  
  }
  
  public void changePlayState()
  {
      if(this.mp.isPlaying())
          this.mp.pause();
      else
          this.mp.start();
  }
  }
  </code></pre>
  
  <p>When i run this code there are multiple issues in it.</p>
  
  <p>1) First two items/videos buffers and play fine. But when i scroll it does not load third video and first video also gets removed from the list. </p>
  
  <p>2) On scroll videos/list items starts buffering again for the item that was already buffered.</p>
  
  <p>3) On fast scroll list gets too laggy and get stuck and crashes.</p>
  
  <p>Attached is the image of logcat that i get while list scroll and video playing.</p>
  
  <p><img src="https://i.stack.imgur.com/pt1Za.png" alt="enter image description here"></p>
  
  <p>Can anyone guide me through this? What is the right way to create a list like vine app?</p>