我认为我的大部分代码都是正确的。我正在尝试从我的SD卡中取出视频(Uri),将它们更改为位图并将其放入ThumbnailUtils
(如堆栈中所示),如下所示:
Uri uri = Uri.fromFile(singleFile);
// create thumbnail: MINI_KIND: 512 x 384 thumbnail
bitmapThumb = ThumbnailUtils.createVideoThumbnail(uri.getPath(),MediaStore.Video.Thumbnails.MINI_KIND);
这段代码似乎是正确的。它变得复杂的地方是我使用的是模型和适配器,所以要经过几个步骤。
Uri
方法将Bitmap
更改为ThumbnailUtils
。VideoGridItem
对象getVideo()
,从我的模型对象中获取位图ImageView
在这些步骤中可能会遗漏一些东西。我记录了这个:Bitmap bm = videoGridItem.getVideo();
奇怪的是,bm
返回null。这是有道理的,因为我在我的视频所在的地方什么都看不到。
下面的截图显示代码确实从我的SD卡中提取了我的1个视频(因此我的文件I / O可能还可以)并用占位符图像填充网格的其余部分,但我不知道为什么它没有显示视频缩略图。没有崩溃或任何东西,只是没有缩略图。谢谢你的帮助。
VideoTab.java
package org.azurespot.cutecollection.videotab;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import org.azurespot.R;
import java.io.File;
import java.util.ArrayList;
/**
* Created by mizu on 2/8/15.
*/
public class VideoTab extends Fragment {
ArrayList<VideoGridItem> videoList = new ArrayList<>();
ArrayAdapter<VideoGridItem> adapter;
private String[] numberSDCardFiles = null;
File[] files;
Bitmap bitmapThumb;
VideoGridItem videoGridItem;
VideoGridItem drawableObject;
public VideoTab() {
super();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.video_tab, container, false);
// Create the Custom Adapter Object
adapter = new GridViewVideoAdapter(getActivity(), videoList);
// with fragments, make sure you include the rootView when finding id
GridView gridView = (GridView) v.findViewById(R.id.video_grid);
gridView.setAdapter(adapter);
if(adapter.getCount() == 0) {
// load contents of SD card
loadVideos();
// turn drawable into an object of type Bitmap
drawableObject = new VideoGridItem(BitmapFactory.decodeResource(getResources(),
R.drawable.ic_video_placeholder));
// add the default icons remaining, to GridView, if less than 14 files on SD card
for (int i = 0; i < (14 - numberSDCardFiles.length); i++) {
adapter.add(drawableObject);
adapter.notifyDataSetChanged();
}
}
return v;
}
public void loadVideos() {
try {
// gets directory Cute Videos from sd card
File cuteVideosDir = new File(Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_MOVIES), "Cute Videos");
files = cuteVideosDir.listFiles();
for (File singleFile : files) {
Uri uri = Uri.fromFile(singleFile);
// create thumbnail: MINI_KIND: 512 x 384 thumbnail
bitmapThumb = ThumbnailUtils.createVideoThumbnail(uri.getPath(),
MediaStore.Video.Thumbnails.MINI_KIND);
videoGridItem = new VideoGridItem(bitmapThumb);
Log.d("TAG", "Value of videoGridItem: " + videoGridItem);
adapter.add(videoGridItem);
adapter.notifyDataSetChanged();
}
} catch (Exception e) {
e.printStackTrace();
}
// get number of files in Cute Videos directory
numberSDCardFiles = new String[files.length];
}
}
GridViewVideoAdapter.java
package org.azurespot.cutecollection.videotab;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import org.azurespot.R;
import java.util.ArrayList;
/**
* Created by mizu on 2/8/15.
*/
public class GridViewVideoAdapter extends ArrayAdapter<VideoGridItem> {
ViewHolder holder = null;
int position;
public GridViewVideoAdapter(Context context, ArrayList<VideoGridItem> videos) {
super(context, 0, videos);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
this.position = position;
if (v == null) {
v = LayoutInflater.from(getContext())
.inflate(R.layout.video_grid_item, parent, false);
holder = new ViewHolder();
holder.imageView = (ImageView) v.findViewById(R.id.video_grid_view);
// stores holder with view
v.setTag(holder);
} else {
holder = (ViewHolder)v.getTag();
}
// gets position of whichever photo you click on in the GridView
final VideoGridItem videoGridItem = getItem(position);
if (videoGridItem != null) {
Bitmap bm = videoGridItem.getVideo();
Log.d("TAG", "Value of bm: " + bm);
holder.imageView.setImageBitmap(bm);
// positioning the image in the GridView slot
holder.imageView.setLayoutParams(new LinearLayout.LayoutParams(512, 384));
}
return v;
}
public class ViewHolder{
ImageView imageView;
}
}
VideoGridItem.java
package org.azurespot.cutecollection.videotab;
import android.graphics.Bitmap;
/**
* Created by mizu on 3/28/15.
*/
public class VideoGridItem {
private Bitmap video;
public VideoGridItem(Bitmap video) {
super();
this.video = video;
}
public Bitmap getVideo() {
return video;
}
public void setVideo(Bitmap video) {
this.video = video;
}
}
答案 0 :(得分:1)
毕竟我的视频保存代码(在另一项活动中)不正确。我认为它没有任何错误,因为视频被保存到我的SD卡就好了。但我没有意识到的是他们不能玩。仔细观察后,我发现只保存了指定的文件名,而不是视频的实际Uri
。
其他帖子中关于ThumbnailUtils.createVideoThumbnail()
的内容确实是正确的:如果视频文件损坏或无法操作,它返回null
的唯一时间。所以,一旦我解决了这个问题,一切都像魅力一样。所以上面的代码实际上是工作代码。
获得的经验:不要假设您的SD卡目录中有工作视频!即使它是在羊的衣服(mp4文件看起来真的很好),它可能是一个狼在下面。