web-dev-qa-db-ja.com

Youtube APIを使用してYoutubeサムネイルをRecyclerViewに読み込む方法

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 com.google.Android.youtube.player.internal.r$e@4252bcb8 that was originally bound here

サムネイルの読み込みには時間がかかり、スワイプ時にサムネイルが混在する場合があります。

すべてのYoutubeローダーを解放する機能を追加しました。

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

そして、アクティビティOnstop()からこの関数を呼び出しています:

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

しばらくは正常に機能していましたが、時々クラッシュします。

23
Stranger B.

多分これを試すことができますか? APIは使用しませんが、高速です。

次のURLからPicassoを使用して、画像をリサイクラビューに読み込みます。

https://img.youtube.com/vi/ "動画IDを入力してください" /default.jpg

-編集-

いくつかの研究と実験の後:

デフォルトのフルサイズのサムネイルを取得するには、default.jpgの代わりにこれを行います

https://img.youtube.com/vi/ "動画IDを入力してください" /0.jpg

リンクは次のとおりです。 http://www.reelseo.com/youtube-thumbnail-image/

編集2:

SOで誰かがすでにこの迅速で簡単な解決策で私のような答えを出しており、あなたが選ぶことができるより多くの説明とオプションがあります。

YouTube APIからYouTubeビデオのサムネイルを取得するにはどうすればよいですか?


最終編集:

これは作業コードです。私は最近、APIを使ってアプリを作成しました。そのため、エラーが発生する理由がわかりました。その理由は、ローダーを適切にリリースしていないからです。

2つの方法でローダーを解放できます。

最初

(優先される理由はすぐにわかります)画像がビューに読み込まれ、そのリスナーとOnThumbNailLoadedListenerが呼び出された後にリリースすることをお勧めします。それは私がそれをリリースした場所です(以下のコードに注意を払った場合)。これは、このインスタンスをもう処理する必要がないことを意味します。サムネイルが読み込まれたら完了です。

GetView()は常に呼び出されるため、YouTubeThumbnailLoaderの新しいインスタンスを解放する必要があります。つまり、これらすべてをArrayListに保存する必要があります。アクティビティがonStop()の場合、高度なforループを実行し、それらすべてでリリースを呼び出します。

おそらく最初の方法が好まれる理由がおわかりでしょう。そして、私はあなたが2番目のオプションをしたことを知っているので、最初のオプションを通知するだけで常に動作することが保証されます(少なくとも私の場合)。アクティビティでYouTubeSupportFragmentを使用しましたが、うまくいきました。問題ありません。 2番目のオプションを確実に機能させることはできますが、多くの特殊なケースを処理する必要があると思います。

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) {

        }
    });
29
Arnold Balliu

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>

enter image description here

14
Harish_N
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;
    }
}
1
Ayaz khorajia