Подтвердить что ты не робот

Как загрузить миниатюры Youtube в RecyclerView с использованием API Youtube

Я пытаюсь загрузить миниатюры видео Youtube в RecyclerView. Я сталкиваюсь с некоторыми проблемами.

Вот что я делаю в своем адаптере:

public static class ItemViewHolder extends RecyclerView.ViewHolder {

    private YouTubeThumbnailView thumb;
    public  Post                 post;

    public ItemViewHolder(View v) {
        thumb = (YouTubeThumbnailView) v.findViewById(R.id.youtube_thumbnail);
    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
        if (holder instanceof ItemViewHolder) {

            ((ItemViewHolder) holder).thumb.initialize(YOUTUPEKEY, new YouTubeThumbnailView.OnInitializedListener() {
                @Override
                public void onInitializationSuccess(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader youTubeThumbnailLoader) {
                    youTubeThumbnailLoader.setVideo(VIDEOID);

                }

                @Override
                public void onInitializationFailure(YouTubeThumbnailView youTubeThumbnailView, YouTubeInitializationResult youTubeInitializationResult) {

                }});
}}}

Это прекрасно работает, но я не делаю это правильно. Когда я использую один и тот же адаптер в другом действии, я получаю эту ошибку:

Activity com.example.yasser.version6.Mespublications has leaked ServiceConnection [email protected] that was originally bound here

и для загрузки эскизов требуется время, и иногда они смешиваются между ними при прокрутке.

Я добавил функцию, чтобы освободить все Youtube Loaders:

public void ReleaseLoaders() {
    for (YouTubeThumbnailLoader loader : loaders.values()) {
        loader.release();
    }
}

и я вызываю эту функцию из Activity Onstop():

@Override
public void onStop() {
    super.onStop();
    mAdapter.ReleaseLoaders();
}

Он работал нормально в течение некоторого времени, но иногда случается сбой.

4b9b3361

Ответ 1

Вы можете попробовать это, может быть? Он не использует API, но быстро.

Загрузите изображение в ресайклере с помощью Picasso по этому URL-адресу:

https://img.youtube.com/vi/ "здесь идет ваш идентификатор видео" /default.jpg

- Изменить -

После некоторых исследований и экспериментов:

Чтобы получить миниатюру полного размера по умолчанию, сделайте это вместо default.jpg

https://img.youtube.com/vi/ "здесь идет ваш видео-идентификатор" /0.jpg

Вот ссылка: http://www.reelseo.com/youtube-thumbnail-image/

Изменить 2:

Просто нашлось, что кто-то из SO уже дал ответ, как мой, с помощью этого быстрого и простого решения, и у вас есть больше объяснений и вариантов, которые вы могли бы выбрать.

Как получить миниатюру видео YouTube из API YouTube?


Final Edit:

Это рабочий код. Я вошел и недавно сделал приложение с api, поэтому выяснил, почему вы получаете ошибку. Это потому, что вы не освобождаете загрузчик должным образом.

Вы можете освободить загрузчик/загрузчики двумя способами.

Первая

(Предпочтительно, вы увидите, почему в секунду) Вы захотите выпустить его после того, как изображение будет загружено в поле зрения, а theres - слушатель для него и его имя OnThumbNailLoadedListener. То, где я его выпустил (если вы обратите внимание на приведенный ниже код). Это означает, что вам больше не нужно иметь дело с этим экземпляром. Как только эскиз будет загружен, вы сделали.

Второй

Так как getView() все время вызывает новые экземпляры YouTubeThumbnailLoader, которые вы должны выпустить. Это означает, что вы должны хранить все это в ArrayList. Вы просто выполняете продвинутый для цикла и вызова релиз во всех случаях, когда активность onStop();

Теперь вы, вероятно, понимаете, почему первый способ является предпочтительным. И я знаю, что вы сделали второй вариант, поэтому просто сообщив, что первый вариант всегда будет гарантированно работать (по крайней мере, в моем случае). Я использовал функцию YouTubeSupportFragment в Activity, и она отлично работала. Никаких проблем. Вы можете определенно сделать второй вариант работы, но вам придется обрабатывать множество особых случаев, я думаю.

final YouTubeThumbnailView youTubeThumbnailView = (YouTubeThumbnailView) convertView.findViewById(R.id.show_episode_thumbnail);
    youTubeThumbnailView.initialize(DeveloperKey.DEVELOPER_KEY, new YouTubeThumbnailView.OnInitializedListener() {
        @Override
        public void onInitializationSuccess(YouTubeThumbnailView youTubeThumbnailView, final YouTubeThumbnailLoader youTubeThumbnailLoader) {
            youTubeThumbnailLoader.setVideo(videoId);
            youTubeThumbnailLoader.setOnThumbnailLoadedListener(new YouTubeThumbnailLoader.OnThumbnailLoadedListener() {
                @Override
                public void onThumbnailLoaded(YouTubeThumbnailView youTubeThumbnailView, String s) {
                    youTubeThumbnailLoader.release();
                }

                @Override
                public void onThumbnailError(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader.ErrorReason errorReason) {

                }
            });
        }

        @Override
        public void onInitializationFailure(YouTubeThumbnailView youTubeThumbnailView, YouTubeInitializationResult youTubeInitializationResult) {

        }
    });

Ответ 2

В onBindViewHolder вы пытаетесь инициализировать один и тот же YoutubeThumbnailView снова и снова, вместо этого вы можете инициализировать его один раз, когда представления создаются в onCreateViewHolder. Установив видео Id в качестве тега на YoutubeThumbnailView, вы можете предотвратить смешение (или) неправильной загрузки эскизов.


адаптер.

    private class ThumbnailAdapter extends RecyclerView.Adapter{

    private final int UNINITIALIZED = 1;
    private final int INITIALIZING = 2;
    private final int INITIALIZED = 3;
    private int blackColor = Color.parseColor("#FF000000");
    private int transparentColor = Color.parseColor("#00000000");

    public class VideoViewHolder extends RecyclerView.ViewHolder{

        public YouTubeThumbnailView ytThubnailView = null;
        public ImageView ivYtLogo = null;
        public TextView tvTitle = null;

        public VideoViewHolder(View itemView) {
            super(itemView);
            ytThubnailView = (YouTubeThumbnailView) itemView.findViewById(R.id.yt_thumbnail);
            ivYtLogo = (ImageView) itemView.findViewById(R.id.iv_yt_logo);
            tvTitle = (TextView) itemView.findViewById(R.id.tv_title);

            initialize();
        }

        public void initialize(){
            ivYtLogo.setBackgroundColor(blackColor);
            ytThubnailView.setTag(R.id.initialize, INITIALIZING);
            ytThubnailView.setTag(R.id.thumbnailloader, null);
            ytThubnailView.setTag(R.id.videoid, "");

            ytThubnailView.initialize(API_KEY, new YouTubeThumbnailView.OnInitializedListener() {
                @Override
                public void onInitializationSuccess(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader youTubeThumbnailLoader) {
                    ytThubnailView.setTag(R.id.initialize, INITIALIZED);
                    ytThubnailView.setTag(R.id.thumbnailloader, youTubeThumbnailLoader);

                    youTubeThumbnailLoader.setOnThumbnailLoadedListener(new YouTubeThumbnailLoader.OnThumbnailLoadedListener() {
                        @Override
                        public void onThumbnailLoaded(YouTubeThumbnailView youTubeThumbnailView, String loadedVideoId) {
                            String currentVideoId = (String) ytThubnailView.getTag(R.id.videoid);
                            if(currentVideoId.equals(loadedVideoId)) {
                                ivYtLogo.setBackgroundColor(transparentColor);
                            }
                            else{
                                ivYtLogo.setBackgroundColor(blackColor);
                            }
                        }

                        @Override
                        public void onThumbnailError(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader.ErrorReason errorReason) {
                            ivYtLogo.setBackgroundColor(blackColor);
                        }
                    });

                    String videoId = (String) ytThubnailView.getTag(R.id.videoid);
                    if(videoId != null && !videoId.isEmpty()){
                        youTubeThumbnailLoader.setVideo(videoId);
                    }
                }

                @Override
                public void onInitializationFailure(YouTubeThumbnailView youTubeThumbnailView, YouTubeInitializationResult youTubeInitializationResult) {
                    ytThubnailView.setTag(R.id.initialize, UNINITIALIZED);
                    ivYtLogo.setBackgroundColor(blackColor);
                }
            });
        }
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = getLayoutInflater().inflate(R.layout.row_video_item, parent, false);
        VideoViewHolder videoViewHolder = new VideoViewHolder(view);
        return videoViewHolder;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        final Entities e = entities.get(position);
        final VideoViewHolder videoViewHolder = (VideoViewHolder) holder;
        videoViewHolder.tvTitle.setText(e.name);
        videoViewHolder.ivYtLogo.setVisibility(View.VISIBLE);
        videoViewHolder.ytThubnailView.setTag(R.id.videoid, e.id);
        videoViewHolder.ivYtLogo.setBackgroundColor(blackColor);

        int state = (int) videoViewHolder.ytThubnailView.getTag(R.id.initialize);

        if(state == UNINITIALIZED){
            videoViewHolder.initialize();
        }
        else if(state == INITIALIZED){
            YouTubeThumbnailLoader loader = (YouTubeThumbnailLoader) videoViewHolder.ytThubnailView.getTag(R.id.thumbnailloader);
            loader.setVideo(e.id);
        }
    }

    @Override
    public int getItemCount() {
        return entities.size();
    }
}

Макет, используемый для каждой строки.

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

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="200dp">

    <com.google.android.youtube.player.YouTubeThumbnailView
        android:id="@+id/yt_thumbnail"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <ImageView
        android:id="@+id/iv_yt_logo"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="center"
        android:src="@mipmap/youtube_play"
        android:background="#00000000"
        android:layout_centerInParent="true"/>

</RelativeLayout>

<TextView
    android:id="@+id/tv_title"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textColor="#FF000000"
    android:textSize="16sp"
    android:text="Title"/>

<View
    android:id="@+id/seperator"
    android:layout_width="match_parent"
    android:layout_height="2dp"
    android:layout_marginTop="5dp"
    android:layout_marginBottom="5dp"
    android:background="#FF642108"/>

</LinearLayout>

tags.xml.

Местоположение: src/main/res/values ​​/tags.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<item type="id" name="initialize" />
<item type="id" name="videoid"/>
<item type="id" name="thumbnailloader"/>
</resources>

введите описание изображения здесь

Ответ 3

public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.VideoHolder> {

    private List<VideoPojo> listvideo;
    private VideoPojo videoPojo;
    private Context mContext;
    private boolean readyForLoadingYoutubeThumbnail = true;
    String KEY = "AIzaSyA5kyaLgS7MKxS19uHf2CUsIOmDkv92DGU";

    public VideoAdapter(Context context, List<VideoPojo> listvideo) {
        this.listvideo = listvideo;
        this.mContext = context;
        videoPojo = new VideoPojo();
    }

    @Override
    public VideoAdapter.VideoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.video_layout, parent, false);
        return new VideoHolder(view);
    }

    @Override
    public void onBindViewHolder(final VideoAdapter.VideoHolder holder, final int position) {

        holder.murl.setText(listvideo.get(position).getVideoUrl());
        final String url = listvideo.get(position).getVideoUrl();
        Log.d(TAG, "readyForLoadingYoutubeThumbnail" + readyForLoadingYoutubeThumbnail);
        if (readyForLoadingYoutubeThumbnail) {
            Log.d(TAG, "initializing for youtube thumbnail view...");
            readyForLoadingYoutubeThumbnail = false;
            holder.youTubeThumbnailView.initialize(KEY, new YouTubeThumbnailView.OnInitializedListener() {
                @Override
                public void onInitializationSuccess(final YouTubeThumbnailView youTubeThumbnailView, final YouTubeThumbnailLoader youTubeThumbnailLoader) {

                    youTubeThumbnailLoader.setVideo(url);
                    youTubeThumbnailLoader.setOnThumbnailLoadedListener(new YouTubeThumbnailLoader.OnThumbnailLoadedListener() {

                        @Override
                        public void onThumbnailLoaded(YouTubeThumbnailView childYouTubeThumbnailView, String s) {
                            holder.loding.setVisibility(View.GONE);
                            youTubeThumbnailLoader.release(); // spy ga memory lick
                        }

                        @Override
                        public void onThumbnailError(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader.ErrorReason errorReason) {
                            youTubeThumbnailLoader.release(); // spy ga memory lick
                        }
                    });

                    readyForLoadingYoutubeThumbnail = true;
                }

                @Override
                public void onInitializationFailure(YouTubeThumbnailView youTubeThumbnailView, YouTubeInitializationResult youTubeInitializationResult) {
                    //do nohing.. ada error, tambahin method ini jalan, error-nya lupa...
                    readyForLoadingYoutubeThumbnail = true;
                }
            });
        }
        holder.mdelate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                deleteVideoAlertDialog(listvideo.get(holder.getAdapterPosition()).getId(), holder.getAdapterPosition());
            }
        });

    }

    @Override
    public int getItemCount() {
        // Log.v(VideoAdapter.class.getSimpleName(), "" + listvideo.size());
        return listvideo.size();
    }

    public class VideoHolder extends RecyclerView.ViewHolder {

        YouTubeThumbnailView youTubeThumbnailView;
        protected FrameLayout playButton;
        TextView murl, mdelate;
        ImageView loding;

        public VideoHolder(View itemView) {
            super(itemView);
            mdelate = itemView.findViewById(R.id.mdelate);
            murl = itemView.findViewById(R.id.murl);
            playButton = itemView.findViewById(R.id.btnYoutube_player);
            youTubeThumbnailView = itemView.findViewById(R.id.youtube_thumbnail);
            loding = itemView.findViewById(R.id.loding);

            playButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int position = getAdapterPosition();
                    String url = listvideo.get(position).getVideoUrl();
                    Toast.makeText(mContext, url, Toast.LENGTH_SHORT).show();
                    Intent intent = YouTubeStandalonePlayer.createVideoIntent((Activity) mContext,
                            KEY, url, 100, false, true);
                    mContext.startActivity(intent);
                }
            });
        }

    }

    private void deleteVideoAlertDialog(final int row_id, final int adapterPosition) {
        final AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);

        // Setting Dialog Title
        alertDialog.setTitle("Delete");
        // Setting Dialog Message
        alertDialog.setMessage("Are you sure you want to delete this video");
        alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                if (SQLiteHelper.deleteUser(mContext, row_id)) {
                    listvideo.remove(adapterPosition);
                    notifyItemRemoved(adapterPosition);
                    notifyItemRangeChanged(adapterPosition, listvideo.size());
                } else {
                    Toast.makeText(mContext, "internal issue ", Toast.LENGTH_SHORT).show();
                }
            }
        });
        // Setting Negative "NO" Button
        alertDialog.setNegativeButton("No", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                // Write your code here to invoke NO event
                dialog.cancel();
            }
        });
        // Showing Alert Message
        alertDialog.show();

    }

    public boolean addNewVideo(String Url, Context context) {
        videoPojo.setVideoUrl(Url);
        SQLiteHelper sqLiteHelper = new SQLiteHelper(context);
        if (sqLiteHelper.addNewVideo(context, videoPojo)) {
            listvideo.add(videoPojo);
            notifyDataSetChanged();
            Toast.makeText(context, "video Saved", Toast.LENGTH_SHORT).show();
            return true;
        }
        return false;
    }
}

Ответ 4

получить высококачественное изображение с этого URL:

https://img.youtube.com/vi/<VIDEO_ID_HERE>/maxresdefault.jpg

а затем с помощью библиотеки Picasso или Glide загрузите это.

для этого видео "https://www.youtube.com/watch?v=BEScHJrjsmU" VIDEO_ID - "BEScHJrjsmU"