Android Rxjava3 使用场景

 * 接口二
 * 获取热词
 * @return
 */
@GET("hotkey/json")
Observable<BaseResponse<List<HotKeyResp.DataBean>>> getHotKey();

}


#### 1、多任务嵌套回调


场景:比如调用接口一有回调后才能调用接口二,如果接口一调用失败不再调用接口二。下面是二种写法。


写法一,代码如下:



//为了看清楚代码,没有使用lambda简化
//接口一
Observable<BaseResponse> articleList = ApiManager.getInstance().getApiService().getArticleList();
//接口二
Observable<BaseResponse<List<HotKeyResp.DataBean>>> hotKey = ApiManager.getInstance().getApiService().getHotKey();
Observable.just(articleList)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(new Function<Observable<BaseResponse>, Observable<BaseResponse<List<HotKeyResp.DataBean>>>>() {
@Override
public Observable<BaseResponse<List<HotKeyResp.DataBean>>> apply(Observable<BaseResponse> baseResponseObservable) throws Throwable {
//处理第一个请求返回的数据
if(baseResponseObservable!=null) mTv.setText(baseResponseObservable.blockingSingle().toString());
return hotKey; //发起第二次网络请求
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Observable<BaseResponse<List<HotKeyResp.DataBean>>>>() {
@Override
public void accept(Observable<BaseResponse<List<HotKeyResp.DataBean>>> baseResponseObservable) throws Throwable {
//处理第二次网络请求的结果
if(baseResponseObservable!=null) mTvTwo.setText(baseResponseObservable.blockingSingle().toString());
}
}, new Consumer() {
@Override
public void accept(Throwable throwable) throws Throwable {
//异常的处理:比如Dialog的Dismiss,缺省页展示等
//注意:如果第一个网络请求异常,整个事件会中断,不会执行第二个网络请求,如果多个请求同理
//但是请求成功的还是能正常处理
LogUtil.e(throwable.toString());
}
});


写法二,代码如下:



//为了看清楚代码,没有使用lambda简化
//接口一
Observable<BaseResponse> articleList = ApiManager.getInstance().getApiService().getArticleList();
//接口二
Observable<BaseResponse<List<HotKeyResp.DataBean>>> hotKey = ApiManager.getInstance().getApiService().getHotKey();
//请求第一个
articleList.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(new Consumer<BaseResponse>() {
@Override
public void accept(BaseResponse articleListRespBaseResponse) throws Throwable {
//处理第一个网络请求的结果
if(articleListRespBaseResponse!=null) mTv.setText(articleListRespBaseResponse.toString());
}
}).observeOn(Schedulers.io())
.flatMap(new Function<BaseResponse, ObservableSource<BaseResponse<List<HotKeyResp.DataBean>>>>() {
@Override
publ

### Python实现视频分割处理 要通过Python实现视频分割,可以采用多种方式。以下是基于`PySceneDetect`库以及FFmpeg工具的解决方案。 #### 方法一:使用 PySceneDetect 进行场景检测并分割视频 PySceneDetect 是一种专门用于视频场景检测和分割的工具[^2]。它能够识别视频中的不同场景,并根据设定的阈值自动生成分割点。具体操作如下: 1. **安装依赖项** 需要先安装 `scenedetect` 库及其所需的外部工具(如 FFmpeg 或 mkvmerge)。 ```bash pip install scenedetect ``` 2. **编写脚本** 下面是一个简单的例子,展示如何利用 PySceneDetect 对视频进行分割: ```python import scenedetect from scenedetect.video_manager import VideoManager from scenedetect.scene_manager import SceneManager from scenedetect.detectors import ContentDetector video_path = 'input_video.mp4' output_dir = './output_scenes/' # 创建VideoManager对象 video_manager = VideoManager([video_path]) scene_manager = SceneManager() # 设置场景变化检测器 scene_manager.add_detector(ContentDetector(threshold=30.0)) base_timecode = video_manager.get_base_timecode() try: # 初始化视频管理器 video_manager.set_downscale_factor() video_manager.start() # 执行场景检测 scene_manager.detect_scenes(frame_source=video_manager) # 获取场景列表 scene_list = scene_manager.get_scene_list(base_timecode) print('Detected scenes:', scene_list) # 保存分割后的视频片段到指定目录 for i, scene in enumerate(scene_list): start_time = str(scene[0].get_seconds()) end_time = str(scene[1].get_seconds()) command = f"ffmpeg -i {video_path} -ss {start_time} -to {end_time} -c copy {output_dir}/scene_{i}.mp4" os.system(command) finally: video_manager.release() ``` 上述代码会读取输入视频文件,执行场景检测,并按照检测结果将视频切分为多个独立的小片段。 --- #### 方法二:手动设置时间间隔进行视频分割 如果不需要复杂的场景检测,而是希望简单地按固定的时间间隔来分割视频,则可以直接调用 FFmpeg 工具完成此任务[^3]。下面提供了一个封装好的函数示例: ```python import subprocess def split_video_by_interval(input_file, interval_sec, output_template="clip_%03d.mp4"): """ 按照给定的时间间隔分割视频 :param input_file: 输入视频路径 :param interval_sec: 时间间隔(秒) :param output_template: 输出文件名模板,默认为 clip_XXX.mp4 """ duration_command = ['ffprobe', '-i', input_file, '-show_entries', 'format=duration', '-v', 'quiet', '-of', 'csv=%s' % ("p=0")] result = subprocess.run(duration_command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) total_duration = float(result.stdout.strip()) # 总时长(单位:秒) current_start = 0 index = 1 while current_start < total_duration: next_end = min(current_start + interval_sec, total_duration) ffmpeg_cmd = [ "ffmpeg", "-i", input_file, "-ss", str(current_start), "-to", str(next_end), "-c:v", "copy", "-c:a", "copy", output_template.replace("%03d", "%03d" % (index,)) ] subprocess.call(ffmpeg_cmd) current_start += interval_sec index += 1 ``` 该函数接受三个参数:输入视频路径、每段视频持续时间和输出文件命名规则。运行后即可得到一系列短片断。 --- #### 注意事项 - 如果需要更精确控制或者支持更多格式转换选项,请考虑引入额外插件或调整命令行参数。 - 上述两种方案均需确保系统已正确配置好 FFmpeg 路径环境变量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值