- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我希望在 Flutter 中重新创建 Snapchat 的连续视频格式。由于 video_player
缺少视频结束时的回调(否则容易出现回调 hell ),我想知道是否有人对构建这样的东西有一些指示。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
void main() {
runApp(MaterialApp(
title: 'My app', // used by the OS task switcher
home: MyHomePage(),
));
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<VideoPlayerController> _controllers = [];
VoidCallback listener;
bool _isPlaying = false;
int _current = 0;
@override
void initState() {
super.initState();
// Add some sample videos
_controllers.add(VideoPlayerController.network(
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
));
_controllers.add(VideoPlayerController.network(
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
));
_controllers.add(VideoPlayerController.network(
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
));
this.tick();
// Try refreshing by brute force (this isn't going too well)
new Timer.periodic(Duration(milliseconds: 100), (Timer t) {
int delta = 99999999;
if(_controllers[_current].value != null) {
delta = (_controllers[_current].value.duration.inMilliseconds - _controllers[_current].value.position.inMilliseconds);
}
print("Tick " + delta.toString());
if(delta < 500) {
_current += 1;
this.tick();
}
});
}
void tick() async {
print("Current: " + _current.toString());
await _controllers[_current].initialize();
await _controllers[_current].play();
print("Ready");
setState((){
_current = _current;
});
}
@override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: _controllers[_current].value.aspectRatio,
// Use the VideoPlayer widget to display the video
child: VideoPlayer(_controllers[_current]),
);
}
}
我现在播放的是第一个视频,但第一个和第二个之间有很长的延迟。我相信这与我无法摆脱附加到第 0 项的监听器有关。
最佳答案
初始化网络 VideoPlayerController
可能需要一些时间才能完成。您可以在播放当前视频的同时初始化下一个视频的 Controller 。这将占用更多内存,但我认为如果您只预缓冲一个或两个视频,它不会产生大问题。然后,当按下下一个或上一个按钮时,视频将准备好播放。
这是我的解决方法。它是功能性的,它预缓冲上一个和下一个视频,完成后跳到下一个视频,显示当前位置和缓冲区,长按暂停和播放。
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
main() {
runApp(MaterialApp(
home: VideoPlayerDemo(),
));
}
class VideoPlayerDemo extends StatefulWidget {
@override
_VideoPlayerDemoState createState() => _VideoPlayerDemoState();
}
class _VideoPlayerDemoState extends State<VideoPlayerDemo> {
int index = 0;
double _position = 0;
double _buffer = 0;
bool _lock = true;
Map<String, VideoPlayerController> _controllers = {};
Map<int, VoidCallback> _listeners = {};
Set<String> _urls = {
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4#1',
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4#2',
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4#3',
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4#4',
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4#5',
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4#6',
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4#7',
};
@override
void initState() {
super.initState();
if (_urls.length > 0) {
_initController(0).then((_) {
_playController(0);
});
}
if (_urls.length > 1) {
_initController(1).whenComplete(() => _lock = false);
}
}
VoidCallback _listenerSpawner(index) {
return () {
int dur = _controller(index).value.duration.inMilliseconds;
int pos = _controller(index).value.position.inMilliseconds;
int buf = _controller(index).value.buffered.last.end.inMilliseconds;
setState(() {
if (dur <= pos) {
_position = 0;
return;
}
_position = pos / dur;
_buffer = buf / dur;
});
if (dur - pos < 1) {
if (index < _urls.length - 1) {
_nextVideo();
}
}
};
}
VideoPlayerController _controller(int index) {
return _controllers[_urls.elementAt(index)];
}
Future<void> _initController(int index) async {
var controller = VideoPlayerController.network(_urls.elementAt(index));
_controllers[_urls.elementAt(index)] = controller;
await controller.initialize();
}
void _removeController(int index) {
_controller(index).dispose();
_controllers.remove(_urls.elementAt(index));
_listeners.remove(index);
}
void _stopController(int index) {
_controller(index).removeListener(_listeners[index]);
_controller(index).pause();
_controller(index).seekTo(Duration(milliseconds: 0));
}
void _playController(int index) async {
if (!_listeners.keys.contains(index)) {
_listeners[index] = _listenerSpawner(index);
}
_controller(index).addListener(_listeners[index]);
await _controller(index).play();
setState(() {});
}
void _previousVideo() {
if (_lock || index == 0) {
return;
}
_lock = true;
_stopController(index);
if (index + 1 < _urls.length) {
_removeController(index + 1);
}
_playController(--index);
if (index == 0) {
_lock = false;
} else {
_initController(index - 1).whenComplete(() => _lock = false);
}
}
void _nextVideo() async {
if (_lock || index == _urls.length - 1) {
return;
}
_lock = true;
_stopController(index);
if (index - 1 >= 0) {
_removeController(index - 1);
}
_playController(++index);
if (index == _urls.length - 1) {
_lock = false;
} else {
_initController(index + 1).whenComplete(() => _lock = false);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Playing ${index + 1} of ${_urls.length}"),
),
body: Stack(
children: <Widget>[
GestureDetector(
onLongPressStart: (_) => _controller(index).pause(),
onLongPressEnd: (_) => _controller(index).play(),
child: Center(
child: AspectRatio(
aspectRatio: _controller(index).value.aspectRatio,
child: Center(child: VideoPlayer(_controller(index))),
),
),
),
Positioned(
child: Container(
height: 10,
width: MediaQuery.of(context).size.width * _buffer,
color: Colors.grey,
),
),
Positioned(
child: Container(
height: 10,
width: MediaQuery.of(context).size.width * _position,
color: Colors.greenAccent,
),
),
],
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FloatingActionButton(onPressed: _previousVideo, child: Icon(Icons.arrow_back)),
SizedBox(width: 24),
FloatingActionButton(onPressed: _nextVideo, child: Icon(Icons.arrow_forward)),
],
),
);
}
}
所有逻辑都存在于状态对象中,因此使其变脏。我将来可能会把它变成一个包。
关于flutter - 如何在 video_player 上无延迟地顺序播放视频?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55887282/
我正在使用一个简单的脚本来延迟加载页面上的所有图像;图像源的路径包含在 data-src 属性中,然后放入 img 标记的实际 src 属性中。几乎大多数(?)延迟加载方法的实现都是如何工作的。 这是
我有一个具有多层 (SKNodes) 背景、游戏层、前景和 HUD 的场景,每个场景中都有多个 SKSpriteNode,用于滚动和您可以收集和点击的对象。 hud 层只有一个 SKSpriteNod
我有一个 Controller 函数来创建一些东西。调用该函数时,将运行 setInterval 来获取项目的状态。 这是服务: (function () { 'use strict';
在我的应用程序中,我播放音频直播,延迟非常重要。我正在使用 AVPlayer,但启动需要 5-6 秒,并且我需要最多 3 秒的延迟。我怎样才能更快地开始播放并减少延迟?设置一个小缓冲区就可以了?如何使
我有一个恼人的问题。我有这个简单的服务器代码(比方说): #!/usr/bin/env python3 import wsgiref.simple_server def my_func(env, st
我是 jquery deferreds 的新手。这里我有一个简单的example 。 谁能告诉我为什么在其他函数完成之前就触发完成函数(“现在是我的时间”)? 这里的人 example还创建一个延迟对
正在放置关闭 之前的标签标记相同的 sa 将它们放在 中部分并指定 defer="defer"属性? 最佳答案 是/否。 是的,因为放置 defer 标签会等到文档加载完毕后再执行。 否,因为放置
我知道Javascript没有delay(500)方法,它会延迟执行500毫秒,所以我一直试图通过使用setTimeout和setInterval来解决这个问题。 for(var i =0; i< 1
我们有一个读写主服务器和复制的从读服务器。在某些网络用例中,数据被发布并立即读取以发送回服务器。立即读取是在读取从属设备上完成的,由于延迟,数据尚未在那里更新。 我知道这可能是复制设置的一个常见问题,
我有以下 dag 设置以从 2015 年开始运行追赶。对于每个执行日期,任务实例在一分钟内完成。但是,第二天的任务仅在 5 分钟窗口内开始。例如。上午 10:00、上午 10:05、上午 10:10
当我在 WatchKit 中推送一个新 Controller 并在新 Controller 的awakeWithContext: 方法中使用 setTitle 时,它需要一秒钟左右来设置标题,直到
我将图像显示为 SVG 文件和文本。 出于某种原因,svg 图像的渲染速度比屏幕的其余部分慢,从而导致延迟,这对用户体验不利。 这种延迟正常吗?我该怎么做才能让整个屏幕同时呈现? Row( ma
我正在考虑在我的应用程序中使用 firebase 动态链接。我需要将唯一标识符从电子邮件生成的链接传递到用户应用程序中。当用户安装了应用程序时,这可以正常工作,但是,我对未安装应用程序的方式有些困惑。
您知道如何使用 JQuery 的延迟方法和一个函数来检测所有已更改的表单并将每个表单作为 Ajax 帖子提交吗? 如果我只列出大量表单提交,我可以得到同样的结果,但如果我使用... $('form.c
我需要一种方法来通过回调获取不同的脚本。这个方法工作正常: fetchScripts:function() { var _this=this; $.when( $.aj
我编写了一个 jquery 脚本,允许我淡入和淡出 div,然后重复。该代码运行良好。但是,当我尝试添加延迟(我希望 div 在淡出之前保持几秒钟)时,它无法正常工作。我尝试在代码中的几个地方添加延迟
我正在努力在延迟、带宽和吞吐量之间划清界限。 有人可以用简单的术语和简单的例子来解释我吗? 最佳答案 水比喻: 延迟 是穿过管子所需的时间。 带宽是管有多宽。 水流量为吞吐量 车辆类比: 从源到目的地
我有一个 CRM 系统,当添加联系人时,我想将他们添加到会计系统中。 我在 CRM 系统中设置了一个 Webhook,将联系人传递给 Azure 函数。 Azure 函数连接到会计系统 API 并在那
我有一个 Android AudioTrack,例如: private AudioTrack mAudioTrack; int min = AudioTrack.getMinBufferSize(sa
我正在 React 中开发一个 TODO 应用程序,并尝试构建将删除选中项目延迟 X 秒的功能,并且如果在这段时间内未选中该框,它将不会被删除。 我遇到的主要问题是当用户在同一 X 秒内检查、取消检查
我是一名优秀的程序员,十分优秀!