在列表视图中使用 CachedVideoPlayer
Using a CachedVideoPlayer in a listview
我试图在 listview
中显示视频,这阻止了我在 initState
中声明 videocontroller
。这导致我在应用程序期间不小心多次重绘视频。我收到此错误:
FATAL EXCEPTION: ExoPlayerImplInternal:Handler
然后
java.lang.OutOfMemoryError: OutOfMemoryError thrown while trying to throw OutOfMemoryError; no stack trace available
我目前的实施。它似乎可以工作一段时间,但内存会慢慢增加,直到它已满。我怎样才能以不同的方式实现它?
这是我在流中调用的代码:
Widget getVideoItem(DocumentSnapshot doc) {
if (watchList.contains(doc['user'])) watched = true;
DateTime dateTime = DateTime.parse(doc['time']);
_videoPlayerController = CachedVideoPlayerController.network(doc["downUrl"])
..initialize();
_videoPlayerController.setLooping(true);
_videoPlayerController.play();
volumeOn = sharedPreferences.getBool("vidVol");
if (volumeOn == null) {
sharedPreferences.setBool("vidVol", false);
volumeOn = false;
}
if (volumeOn) {
_videoPlayerController.setVolume(1.0);
} else {
_videoPlayerController.setVolume(0.0);
}
return new FutureBuilder(
future: getUserData(doc["user"]),
builder: (BuildContext context, snapshot) {
return SizedBox(
height: MediaQuery.of(context).size.width + 140,
width: MediaQuery.of(context).size.width,
child: Column(children: <Widget>[
new ListTile(
title: new Text(userInfo),
subtitle: new Text(doc["title"]),
leading: FutureBuilder(
future: getProfUrl(doc),
builder: (BuildContext context, snapshot) {
Widget child;
if (!snapshot.hasData) {
child = _showCircularProgress();
} else {
child = child = new Container(
width: 44.0,
height: 44.0,
child: CachedNetworkImage(
imageUrl: doc["profUrl"],
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
),
),
),
),
);
}
return child;
}),
),
new Padding(
padding: EdgeInsets.fromLTRB(4, 4, 4, 4),
child: FutureBuilder(
future: getDownUrl(doc),
builder: (BuildContext context, snapshot) {
List<Widget> children;
if (!snapshot.hasData) {
children = [_showCircularProgress()];
} else {
children = [
Center(
child: new AspectRatio(
aspectRatio: 1 / 1,
child: Stack(
children: [
VisibilityDetector(
key: Key("unique key"),
onVisibilityChanged: (VisibilityInfo info) {
if (info.visibleFraction > .20) {
_videoPlayerController.pause();
} else {
_videoPlayerController.play();
}
},
child: CachedVideoPlayer(
_videoPlayerController,
)),
IconButton(
icon: volumeOn
? Icon(Icons.volume_up)
: Icon(Icons.volume_off),
onPressed: () {
setState(() {
_videoPlayerController.pause();
sharedPreferences.setBool(
"vidVol", !volumeOn);
});
},
),
],
),
),
)
];
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: children,
),
);
}),
),
new Row(
children: [
new IconButton(
icon: !watched
? new Icon(
Icons.remove_red_eye,
color: Colors.black26,
)
: new Icon(
Icons.remove_red_eye,
color: Colors.blueGrey[400],
),
onPressed: () {
initToggleWatched(watchList, doc["user"], name, position,
secPosition, state, year, user);
}),
Padding(
padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
dateTime.day.toString() +
"/" +
dateTime.month.toString() +
"/" +
dateTime.year.toString(),
style: TextStyle(color: Colors.black26, fontSize: 12),
),
),
),
],
)
]),
);
},
);
}
尝试使带有控制器的小部件成为一个单独的 StatefullWidget
,而不是将所有内容都放在一个地方,并在 initState()
和 dispose()
方法中管理控制器的实例化和处置。
我试图在 listview
中显示视频,这阻止了我在 initState
中声明 videocontroller
。这导致我在应用程序期间不小心多次重绘视频。我收到此错误:
FATAL EXCEPTION: ExoPlayerImplInternal:Handler
然后
java.lang.OutOfMemoryError: OutOfMemoryError thrown while trying to throw OutOfMemoryError; no stack trace available
我目前的实施。它似乎可以工作一段时间,但内存会慢慢增加,直到它已满。我怎样才能以不同的方式实现它?
这是我在流中调用的代码:
Widget getVideoItem(DocumentSnapshot doc) {
if (watchList.contains(doc['user'])) watched = true;
DateTime dateTime = DateTime.parse(doc['time']);
_videoPlayerController = CachedVideoPlayerController.network(doc["downUrl"])
..initialize();
_videoPlayerController.setLooping(true);
_videoPlayerController.play();
volumeOn = sharedPreferences.getBool("vidVol");
if (volumeOn == null) {
sharedPreferences.setBool("vidVol", false);
volumeOn = false;
}
if (volumeOn) {
_videoPlayerController.setVolume(1.0);
} else {
_videoPlayerController.setVolume(0.0);
}
return new FutureBuilder(
future: getUserData(doc["user"]),
builder: (BuildContext context, snapshot) {
return SizedBox(
height: MediaQuery.of(context).size.width + 140,
width: MediaQuery.of(context).size.width,
child: Column(children: <Widget>[
new ListTile(
title: new Text(userInfo),
subtitle: new Text(doc["title"]),
leading: FutureBuilder(
future: getProfUrl(doc),
builder: (BuildContext context, snapshot) {
Widget child;
if (!snapshot.hasData) {
child = _showCircularProgress();
} else {
child = child = new Container(
width: 44.0,
height: 44.0,
child: CachedNetworkImage(
imageUrl: doc["profUrl"],
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
),
),
),
),
);
}
return child;
}),
),
new Padding(
padding: EdgeInsets.fromLTRB(4, 4, 4, 4),
child: FutureBuilder(
future: getDownUrl(doc),
builder: (BuildContext context, snapshot) {
List<Widget> children;
if (!snapshot.hasData) {
children = [_showCircularProgress()];
} else {
children = [
Center(
child: new AspectRatio(
aspectRatio: 1 / 1,
child: Stack(
children: [
VisibilityDetector(
key: Key("unique key"),
onVisibilityChanged: (VisibilityInfo info) {
if (info.visibleFraction > .20) {
_videoPlayerController.pause();
} else {
_videoPlayerController.play();
}
},
child: CachedVideoPlayer(
_videoPlayerController,
)),
IconButton(
icon: volumeOn
? Icon(Icons.volume_up)
: Icon(Icons.volume_off),
onPressed: () {
setState(() {
_videoPlayerController.pause();
sharedPreferences.setBool(
"vidVol", !volumeOn);
});
},
),
],
),
),
)
];
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: children,
),
);
}),
),
new Row(
children: [
new IconButton(
icon: !watched
? new Icon(
Icons.remove_red_eye,
color: Colors.black26,
)
: new Icon(
Icons.remove_red_eye,
color: Colors.blueGrey[400],
),
onPressed: () {
initToggleWatched(watchList, doc["user"], name, position,
secPosition, state, year, user);
}),
Padding(
padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
dateTime.day.toString() +
"/" +
dateTime.month.toString() +
"/" +
dateTime.year.toString(),
style: TextStyle(color: Colors.black26, fontSize: 12),
),
),
),
],
)
]),
);
},
);
}
尝试使带有控制器的小部件成为一个单独的 StatefullWidget
,而不是将所有内容都放在一个地方,并在 initState()
和 dispose()
方法中管理控制器的实例化和处置。