Coder Social home page Coder Social logo

changsanjiang / sjmediacacheserver Goto Github PK

View Code? Open in Web Editor NEW
230.0 7.0 50.0 6.36 MB

A HTTP Media Caching Framework. It can cache FILE or HLS media. 音视频边播边缓存框架, 支持 HLS(m3u8) 和 FILE(mp4, mp3等).

License: MIT License

Ruby 0.73% Objective-C 99.27%
cache media video audio player mp3 mp4 m3u8 hls vod

sjmediacacheserver's Introduction

SJMediaCacheServer

SJMediaCacheServer is a HTTP Media Caching Framework. It can cache FILE or HLS media.

Features

  • Support cache FILE and HLS media.
  • Support prefetch media.

Installation

pod 'SJUIKit/SQLite3', :podspec => 'https://gitee.com/changsanjiang/SJUIKit/raw/master/SJUIKit-YYModel.podspec'
pod 'SJMediaCacheServer'

使用介绍

Usage

  • Play
#import <SJMediaCacheServer/SJMediaCacheServer.h>

    NSURL *URL = [NSURL URLWithString:@"http://.../auido.mp3"];
    NSURL *playbackURL = [SJMediaCacheServer.shared playbackURLWithURL:URL];
    AVPlayer *player = [AVPlayer playerWithURL:playbackURL];
    [player play];
  • Prefetch
#import <SJMediaCacheServer/SJMediaCacheServer.h>
    
    [SJMediaCacheServer.shared prefetchWithURL:URL preloadSize:20 * 1024 * 1024 progress:^(float progress) {
        NSLog(@"%lf", progress);
    } completed:^(NSError * _Nullable error) {
        NSLog(@"%@", error);
    }];
    
    // The task to cancel the current prefetching.
    id<MCSPrefetchTask> task = [SJMediaCacheServer.shared prefetchWithURL:URL preloadSize:20 * 1024 * 1024 progress:^(float progress) {
        NSLog(@"%lf", progress);
    } completed:^(NSError * _Nullable error) {
        NSLog(@"%@", error);
    }];
    // cancel 
    [task cancel];
  • Download request configuration
    SJMediaCacheServer.shared.requestHandler = ^NSMutableURLRequest * _Nullable(NSMutableURLRequest * _Nonnull request) {
        [request addValue:@"value1" forHTTPHeaderField:@"header filed1"];
        [request addValue:@"value2" forHTTPHeaderField:@"header filed2"];
      return request;
    };
  • Other configuration
    @interface SJMediaCacheServer (Convert)

    /// Resolve the identifier of the resource referenced by the URL.
    ///
    ///     The resource identifier represents a unique resource. When different URLs references the same resource, you can set the block to resolve the identifier.
    ///
    ///     This identifier will be used to identify the local cache. The same identifier will references the same cache.
    ///
    @property (nonatomic, copy, nullable) NSString *(^resolveResourceIdentifier)(NSURL *URL); // URL参数不固定时, 请设置该block返回一个唯一标识符

    /// Encode the received data.
    ///
    ///     This block will be invoked when the download server receives the data, where you can perform some encoding operations on the data.
    ///
    @property (nonatomic, copy, nullable) NSData *(^writeDataEncoder)(NSURLRequest *request, NSUInteger offset, NSData *data); // 对下载的数据进行编码

    /// Decode the read data.
    ///
    ///     This block will be invoked when the reader reads the data, where you can perform some decoding operations on the data.
    ///
    @property (nonatomic, copy, nullable) NSData *(^readDataDecoder)(NSURLRequest *request, NSUInteger offset, NSData *data); // 对读取的数据进行解码

    @end


    @interface SJMediaCacheServer (Log)

    /// Whether to open the console log, only in debug mode. release mode will not generate any logs.
    ///
    ///     If yes, the log will be output on the console. The default value is NO.
    ///
    @property (nonatomic, getter=isEnabledConsoleLog) BOOL enabledConsoleLog; // 是否开启控制日志

    @end


    @interface SJMediaCacheServer (Cache)

    /// The maximum number of resources the cache should hold.
    ///
    ///     If 0, there is no count limit. The default value is 0.
    ///
    ///     This is not a strict limit—if the cache goes over the limit, a resource in the cache could be evicted instantly, later, or possibly never, depending on the usage details of the resource.
    ///
    @property (nonatomic) NSUInteger cacheCountLimit; // 个数限制

    /// The maximum length of time to keep a resource in the cache, in seconds.
    ///
    ///     If 0, there is no expiring limit.  The default value is 0.
    ///
    @property (nonatomic) NSTimeInterval maxDiskAgeForCache; // 保存时长限制

    /// The maximum size of the disk cache, in bytes.
    ///
    ///     If 0, there is no cache size limit. The default value is 0.
    ///
    @property (nonatomic) NSUInteger maxDiskSizeForCache; // 缓存占用的磁盘空间限制

    /// The maximum length of free disk space the device should reserved, in bytes.
    ///
    ///     When the free disk space of device is less than or equal to this value, some resources will be removed.
    ///
    ///     If 0, there is no disk space limit. The default value is 0.
    ///
    @property (nonatomic) NSUInteger reservedFreeDiskSpace; // 剩余磁盘空间限制

    /// Empties the cache. This method may blocks the calling thread until file delete finished.
    ///
    - (void)removeAllCaches; // 删除全部缓存
    @end

License

SJMediaCacheServer is released under the MIT license.

Feedback

Reference

sjmediacacheserver's People

Contributors

alex92908 avatar changsanjiang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

sjmediacacheserver's Issues

已崩溃:queue.SJMediaCacheServer EXC_BAD_ACCESS KERN_INVALID_ADDRESS

使用如下方法进行批量prefetch的时候,会出现偶现的crash
`- (void)prefetchVideos
{
NSArray <NSString *>*videoUrl = [self videoSourceUrlStrings];
if (IS_ARRAY_EMPTY(videoUrl)) return;
//缓存开始
[SJMediaCacheServer shared].maxConcurrentPrefetchCount = 10;
[videoUrl enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSURL *storeUrl = [NSURL URLWithString:obj];
[[SJMediaCacheServer shared] prefetchWithURL:storeUrl progress:^(float progress) {
} completed:^(NSError * _Nullable error) {
NSLog(@"缓存结束");
}];
}];
}

  • (NSArray <NSString *> *)videoSourceUrlStrings
    {
    if (IS_ARRAY_EMPTY(self.videoList.records)) return @[];
    return [self.videoList.records valueForKey:@"videoUrl"];
    }
    `

crash的堆栈打印信息如下

Crashed: queue.SJMediaCacheServer
0 libdispatch.dylib 0x4ed4 dispatch_semaphore_signal$VARIANT$mp + 4
1 SJMediaCacheServer 0x3118c -[MCSContents downloadTask:didCompleteWithError:] + 52
2 SJMediaCacheServer 0x32e44 __52-[MCSDownload URLSession:task:didCompleteWithError:]_block_invoke + 216
3 libdispatch.dylib 0x63094 _dispatch_call_block_and_release + 24
4 libdispatch.dylib 0x64094 _dispatch_client_callout + 16
5 libdispatch.dylib 0xa73c _dispatch_lane_serial_drain$VARIANT$mp + 644
6 libdispatch.dylib 0xb1f4 _dispatch_lane_invoke$VARIANT$mp + 408
7 libdispatch.dylib 0x14ec8 _dispatch_workloop_worker_thread + 632
8 libsystem_pthread.dylib 0x1e10 _pthread_wqthread + 284
9 libsystem_pthread.dylib 0x193c start_wqthread + 8

大神能不能帮忙看一下

Crash Bug

'NSInvalidArgumentException', reason: '-[__NSFrozenDictionaryM asset]: unrecognized selector sent to instance 0x11f79f340'
(
0 CoreFoundation 0x00000001a8b05358 7769FFAC-4FCD-332D-A4BE-DA2F0E2FFEA5 + 1250136
1 libobjc.A.dylib 0x00000001a881acc0 objc_exception_throw + 60
2 CoreFoundation 0x00000001a8a04110 7769FFAC-4FCD-332D-A4BE-DA2F0E2FFEA5 + 196880
3 CoreFoundation 0x00000001a8b09b20 7769FFAC-4FCD-332D-A4BE-DA2F0E2FFEA5 + 1268512
4 CoreFoundation 0x00000001a8b0be10 _CF_forwarding_prep_0 + 96
5 SJMediaCacheServer 0x000000010a704ccc __40-[MCSAssetManager _removeAssetsInArray:]_block_invoke + 280
6 CoreFoundation 0x00000001a8ad771c 7769FFAC-4FCD-332D-A4BE-DA2F0E2FFEA5 + 1062684
7 CoreFoundation 0x00000001a89d5978 7769FFAC-4FCD-332D-A4BE-DA2F0E2FFEA5 + 6520
8 SJMediaCacheServer 0x000000010a704b64 -[MCSAssetManager _removeAssetsInArray:] + 180
9 SJMediaCacheServer 0x000000010a702f74 __67-[MCSAssetManager removeAssetsForLastReadingTime:notIn:countLimit:]_block_invoke + 1516
10 SJMediaCacheServer 0x000000010a70f82c mcs_queue_sync + 68
11 SJMediaCacheServer 0x000000010a702958 -[MCSAssetManager removeAssetsForLastReadingTime:notIn:countLimit:] + 204
12 SJMediaCacheServer 0x000000010a702874 -[MCSAssetManager removeAssetsForLastReadingTime:notIn:] + 84
13 SJMediaCacheServer 0x000000010a6f43f8 -[MCSAssetCacheManager _removeAssetsForLimit:] + 772
14 SJMediaCacheServer 0x000000010a6f3d84 -[MCSAssetCacheManager _trim] + 100
15 SJMediaCacheServer 0x000000010a6f3c9c __47-[MCSAssetCacheManager _checkCachesRecursively]_block_invoke_2 + 36
16 libdispatch.dylib 0x000000010afb74d8 _dispatch_client_callout + 20
17 libdispatch.dylib 0x000000010afc6e14 _dispatch_lane_barrier_sync_invoke_and_complete + 172
18 SJMediaCacheServer 0x000000010a70f840 mcs_queue_sync + 88
19 SJMediaCacheServer 0x000000010a6f3c48 __47-[MCSAssetCacheManager _checkCachesRecursively]_block_invoke + 116
20 libdispatch.dylib 0x000000010afb74d8 _dispatch_client_callout + 20
21 libdispatch.dylib 0x000000010afba320 _dispatch_continuation_pop + 572
22 libdispatch.dylib 0x000000010afce224 _dispatch_source_invoke + 1332
23 libdispatch.dylib 0x000000010afc9850 _dispatch_root_queue_drain + 356
24 libdispatch.dylib 0x000000010afca1b8 _dispatch_worker_thread2 + 140
25 libsystem_pthread.dylib 0x00000001a880d6dc _pthread_wqthread + 216
26 libsystem_pthread.dylib 0x00000001a88139c8 start_wqthread + 8
)
2021-09-06 16:52:45.023180+0800 超级雇主[3972:1433736] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSFrozenDictionaryM asset]: unrecognized selector sent to instance 0x11f79f340'

APP freeze/hangs when using in uitableview cell for multiple videos

getting a console error every time during fast scroll UITableview. Every cell contains a video object configure with library playback URL (let playBackUrl = SJMediaCacheServer.shared().playbackURL(with: url)) and play after scroll didEndScrolling. after 2 3 videoes app freezes. No response and throw an error below;
Incorrect NSStringEncoding value 0x0000 detected. Assuming NSASCIIStringEncoding. Will stop this compatibility mapping behavior in the near future

bug

1.缓存 m3u8 视频速度 非常慢(wifi 4G)都测试过
2.缓存m3u8 进度 会从 0.5 开始

prefetchWithURL 不支持断点续传

使用 prefetchWithURL 加载一个视频时,如果中途中断下载(cancel 或者杀掉 app),下次再继续调用 prefetchWithURL 加载同一个视频时会出现 “请求range参数错误!” 异常,此时必须手动清除缓存,再重新下载该视频,希望这块逻辑优化一下

ts片段在seekTime之后无法下载的bug

设备: 在iOS14.4.2下和iOS12.1.4下百分百复现,而在15.1上没有复现
复现步骤
1.创建player

  • (void)avPlayerDemo1 {
    NSString *url = DEMO_URL_HLS;
    NSURL *URL = [NSURL URLWithString:url];
    NSURL *playbackUrl =[SJMediaCacheServer.shared playbackURLWithURL:URL];
    self.avPlayer = [AVPlayer playerWithURL:playbackUrl];
    self.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer];
    self.avPlayerLayer.frame = self.view.bounds;
    [self.view.layer addSublayer:self.avPlayerLayer];
    [self addObservers:self.avPlayer.currentItem];
    }

  • (void)addObservers:(AVPlayerItem*)item {
    [item addObserver:self
    forKeyPath:@"loadedTimeRanges"
    options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
    context:nil];
    [item addObserver:self
    forKeyPath:@"status"
    options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
    context:nil];
    }

  • (void)observeValueForKeyPath:(NSString*)path
    ofObject:(id)object
    change:(NSDictionary*)change
    context:(void*)context {

    if ([path isEqualToString:@"status"]) {
    AVPlayerItem* item = (AVPlayerItem*)object;
    switch (item.status) {
    case AVPlayerItemStatusFailed:
    // [UIView showToast:@"视频播放出错啦~"];
    break;
    case AVPlayerItemStatusUnknown:
    // NSLog(@">>>>>>>>>>>>>>>>>>视频未知状态");
    break;
    case AVPlayerItemStatusReadyToPlay:
    // NSLog(@">>>>>>>>>>>>>>视频已经准备好播放了duration:%lld",self.duration);
    [self.avPlayer play];
    [self.avPlayer seekToTime:CMTimeMake(30000, self.avPlayer.currentItem.asset.duration.timescale)];

        break;
    }
    

    }
    }

当前代码运行起来,就会发现,在低版本中会出现ts片段下载失败的问题,导致界面假死现象。请问这个应该如何解决

导入出错

导入的包含CocoaHTTPServer 出现Implicit declaration of function 'LOG_OBJC_MAYBE' is invalid in C99的错误

prefetching not working properly.

@changsanjiang Precaching is not working properly. Following some scenarios/use cases in which preaching is not working :

Only app dummy URLs are preached properly as per my testing. When we are using other m3u8 URLs then preaching is not working. Steps:
In AppDelegate, we have cleared all caches.
From ViewController we pass the Videos array to VideoFeedViewController and play only the first video and code for prefetching all videos in viewDidLoad. After completing prefetching we switch off the Internet and scroll down to play offline videos (prefetched videos). But only app URLs (SJMediaCacheServer app demo URLs) are prefetched and they will play, but our m3u8 URLs are not playing.
After that, we start our internet connection, and our URLs still not playing. Even sometimes app URLs(SJMediaCacheServer app demo URLs) are also not playing. The only option to play URLs is: kill the app and again start.

The second scenario is: if we have some URLs already cached, then they should play, even with no internet connection. But they are not working as expected.

I am sharing one demo project in which we have two arrays in ViewController Class: videoArray and video1Array. And passed in the action_videoFeed method. videoArray contains all dummy URLs working fine in prefetching, But when we pass video1Array then only initial URLs(SJMediaCacheServer app demo URLs) will be prefetched and after that our URLs will not be prefetched.

Please check I will share one demo project for that to your email address.

播放缓存视频,卡住不动,有时声音还会继续,也偶尔会有可能恢复播放

报错日志:
2021-04-26 20:41:21.708213+0800 treector[44167:11534574] ICSInfo.cpp:236:Deserialize: section length exceeds max SFB
2021-04-26 20:41:21.708483+0800 treector[44167:11534574] ICSInfo.cpp:738:Deserialize: Error deserializing section data
2021-04-26 20:41:21.708676+0800 treector[44167:11534574] SyntacticElements.cpp:41:Deserialize: Error deserializing left channel stream
2021-04-26 20:41:21.708867+0800 treector[44167:11534574] AACDecoder.cpp:148:Deserialize: Error in deserializing element
2021-04-26 20:41:21.709028+0800 treector[44167:11534574] AACDecoder.cpp:220:DecodeFrame: Error deserializing packet
2021-04-26 20:41:21.709212+0800 treector[44167:11534574] [ac] ACMP4AACBaseDecoder.cpp:1337:ProduceOutputBufferList: (0x7ffa9d0dea40) Error decoding packet 492: err = -1, packet length: 505
2021-04-26 20:41:21.709446+0800 treector[44167:11534574] [ac] ACMP4AACBaseDecoder.cpp:1346:ProduceOutputBufferList: '36 2A 72 14 CC 0C 0D 4A 46 6B C0 30 00 78 CF 53 4C 80 DB D6 8C B6 F6 99 8B 3A 9E 5E 82 D6 BB DE 4E CB 25 E8 70 08 4C 3C 1C A3 41 D8 C0 48 E6 FC F6 72 82 3E 24 4C D5 9E 89 17 E2 BD C0 B3 5A 11 8A D9 D1 E6 E2 81 2D 68 38 3F BD 7D 9A 01 FC A0 04 FA 2D BE B8 37 95 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7D 21 19 D4 25 EA 89 63 71 C0 CE 12 6E 2D CC AA 34 A5 55 8A 8A 8C 9E B4 02 61 71 2A 4F CA 7E 91 DD FD 31 89 6E AF A2 B0 16 36 8C 86 FE 7B 8C 97 C6 5E C7 15 ED 7B 01 CD EB 4D F7 13 3E 43 88 BA B1 B4 EA 95 54 FA BD 1F CE CB 0B 4F 85 F6 AB E6 32 90 AF F4 7F 21 6E 42 37 FE 79 CD 2E 8A 4F E1 A1 9A 36 69 AC B3 14 06 39 EB 5E 31 8E D6 B1 0B DD 76 2D 91 2F 7D 2D 64 BB 71 CD 93 30 CE 21 D9 CE 1F B6 A2 4E F7 86 CF 18 67 19 5E CD 27 66 2B 2B 93 A0 BB 17 1C C4 29 E7 D6 B3 73 4F 73 D3 9B A2 69 44 B1 96 7E D1 B1 A9 5B 16 E6 6C 2A 72 B6 BD 89 5E 6B 9D D5 37 1F 03 A0 54 EB 9F 7D 9D F1 35 49 CE C2 A6 BB D9 46 8C 83 8E E1 9F 38 C7 46 E0 EB 5F 8B D3 76 2D E8 EA FD 06 71 F0 57 2A 1F F9 52 E6 BE 03 F9 DC E7 6A F8 AF B5 19 BF FB 6D 55 3C 0A 34 1F 45 C1 FC 5A 23 AD 67 3A C5 C3 D3 5B FE 40 EF 6C C3 02 E0 5B 57 28 26 7B DF AD 9B 9F 93 3B FA 15 96 E3 2D 73 20 62 5B B3 62 E6 99 8D 7B D2 07 B7 04 5A 9B BD 74 8E E1 39 D4 E1 27 47 6D D6 80 02 BD E7 1F FC FF 87 DA 4F 1F 95 F8 9F FA 62 2B 66 98 99 D4 D6 E4 C2 E1 C3 3A A2 F1 D7 32 94 B9 98 85 2C CB 22 E2 2A D9 64 D2 AE 29 B3 AA 24 CE 73 9C 36 60 72 43'
2021-04-26 20:41:21.719200+0800 treector[44167:11534574]
AACDecoder.cpp:192:Deserialize: Unmatched number of channel elements in payload
2021-04-26 20:41:21.719421+0800 treector[44167:11534574] AACDecoder.cpp:220:DecodeFrame: Error deserializing packet
2021-04-26 20:41:21.719839+0800 treector[44167:11534574] [ac] ACMP4AACBaseDecoder.cpp:1337:ProduceOutputBufferList: (0x7ffa9d0dea40) Error decoding packet 493: err = -1, packet length: 505

探讨一下用法

a问题:
不使用 cache,播放的同时,点击下载。会有两个请求。
同样的操作,如果使用 cache。一样有两个请求,区别可能是缓存下载的range,会相对小一些。
在这种情况下,如果用户一直看到视频结束,下载的流量就接近 2倍视频资源(先播放的那部分缓存了,下载的range从那部分之后发出),这样缓存提升较小。

b问题:
上面的场景是没有缓存完的情况,如果通过播放缓存完成,此时进行下载。那么相当于本地copy。但是此时不能清除cache里的源文件,否则cache就失效了(类似demo这种仍然能正常播放和seek是依赖了播放器的缓存,如果是大视频就....),补救措施是切换播放器的播放源到下载源,不好做到无缝衔接。

想问问作者使用的时候是如何应对这两个场景的

可以加一个error报错统一block出来吗

有些业务场景需要针对播放器下载缓存或者解码过程中失败或报错的话 播放器上面提示某种交互。
针对这种场景,可以加一个error报错统一block出来吗,我们不方便直接修改源码,这样不利于后期的更新🙏

crash on iphone 6s 13.7

截屏2020-11-26 下午7 25 24
播放视频时
error message:
Incorrect NSStringEncoding value 0x0000 detected. Assuming NSASCIIStringEncoding. Will stop this compatibility mapping behavior in the near future.

播放m3u8视频一段时间后,会报Domain=NSURLErrorDomain Code=-1005 "网络连接已中断。"错误

播放m3u8视频一段时间后,会报Domain=NSURLErrorDomain Code=-1005 "网络连接已中断。"错误

Domain=NSURLErrorDomain Code=-1005 "网络连接已中断。" UserInfo={NSLocalizedDescription=网络连接已中断。, NSErrorFailingURLStringKey=http://course-video.meipian.me/3auYnFiwCH32B5AV8r0yv_F1GYM=/ltTu3pgLGYLcPsXQ8yD8ol-AwdOP/000072.ts?e=1633946970&token=o8tYTtFAc2_SNrlYQw8lTsYT9B5IUXNBItafEj4f:jiMZfiXrIB3RArORB_Hr95uu0i4, NSErrorFailingURLKey=http://course-video.meipian.me/3auYnFiwCH32B5AV8r0yv_F1GYM=/ltTu3pgLGYLcPsXQ8yD8ol-AwdOP/000072.ts?e=1633946970&token=o8tYTtFAc2_SNrlYQw8lTsYT9B5IUXNBItafEj4f:jiMZfiXrIB3RArORB_Hr95uu0i4, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <0F6B0733-7E3C-4FB4-BF9A-BE92FD7FB31D>.<236>"
), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <0F6B0733-7E3C-4FB4-BF9A-BE92FD7FB31D>.<236>, NSUnderlyingError=0x281879710 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={NSErrorPeerAddressKey=<CFData 0x283402df0 [0x25ffdd430]>{length = 16, capacity = 16, bytes = 0x10022382c0a8002c0000000000000000}}}}
MCSProxyTask: <0x281a60e40>.close { after (36.473433) seconds };

很大概率会出现

预加载视频失败了

Error Domain=lib.changsanjiang.SJMediaCacheServer.error Code=100002 "(null)" UserInfo={URL=https://v.suv666.com/test/material/a67363cde6a5ce0ac5f09ac2b6fdc6a5_360p.mp4, Request=<NSMutableURLRequest: 0x28388c430> { URL: https://v.suv666.com/test/material/a67363cde6a5ce0ac5f09ac2b6fdc6a5_360p.mp4 }, Response=<NSHTTPURLResponse: 0x283a7bf40> { URL: https://v.suv666.com/test/material/a67363cde6a5ce0ac5f09ac2b6fdc6a5_360p.mp4 } { Status Code: 206, Headers {
"Accept-Ranges" = (
bytes
);
"Access-Control-Allow-Origin" = (
"*"
);
"Access-Control-Expose-Headers" = (
"X-Log, X-Reqid"
);
"Access-Control-Max-Age" = (
2592000
);
Age = (
2486964
);
"Ali-Swift-Global-Savetime" = (
1594710439
);
"Cache-Control" = (
"public, max-age=31536000"
);
Connection = (
"keep-alive"
);

集成后使用ZFPlayer 播放转换后的地址报错。

我按照集成步骤集成后,将playbackURLWithURL转换后的地址赋值给ZFPlayer 播放器,播放器无法播放并报错,错误如下:
Error Domain=AVFoundationErrorDomain Code=-11829 "无法打开" UserInfo={NSLocalizedFailureReason=此媒体可能已损坏。, NSLocalizedDescription=无法打开, NSUnderlyingError=0x283d86bb0 {Error Domain=NSOSStatusErrorDomain Code=-12848 "(null)"}}

请问,是不是还需配置什么参数才可以?

For some cases, the app still freeze and also prefetch is fails

I have checked version 1.5.2. Following are my observations:-

  1. In some cases, the app is still freezing. I am sharing with you a video of the demo project I have shared with you last time in your mail ID. Please check the mail for the attached video for the scenario.

  2. I am using the following method to check the cache status.
    if SJMediaCacheServer.shared().isStored(for: URL) {
    print(true)
    } else {
    print(false)
    }

Every time, getting false. Am I missing something or using it wrong method? Please let me know.

  1. When I am using the app for a few minutes and scroll up/down for a lot of videos. After some time, playableURL stops playing videos (for Already cached and new URL both). Only blank space appears. It is the main issue because the user experience is broken in this case.

  2. I am getting some logs in the console like :
    2021-02-26 12:41:41.955388+0530 SJCacheServerDemo[61466:4106476] [connection] nw_connection_add_timestamp_locked_on_nw_queue [C2] Hit maximum timestamp count, will start dropping events

{OptimizedCabacDecoder::UpdateBitStreamPtr} bitstream parsing error!!!!!!!!!!!!!!
{OptimizedCabacDecoder::EndSliceBody} bitstream parsing error!!!!!!!!!!!!!!
{OptimizedCabacDecoder::UpdateBitStreamPtr} bitstream parsing error!!!!!!!!!!!!!!
{OptimizedCabacDecoder::EndSliceBody} bitstream parsing error!!!!!!!!!!!!!!

May help you in debugging the issue.

MCSProxyTask 如何强制取消

哈喽,大佬,咨询下 如果是快速滑动切换短视频(类似视频号)这种场景,如果取消掉快速滑动过程中的task,我这边测试发现任务堆积导致快速滑动后停止,视频播放会等待较久才可以播放(大于5秒)

The app freezing issue still there. When we are playing 2 3 videos on the visible screen.

The warning is gone now, but the app freezing issue still there. When we are playing 2 3 videos on the visible screen (in different UitableviewCells or sometimes in single Cell 2 videos are playing) and scroll up and down then the app freeze/hangs. Sometimes when we navigate to different screens from the video screen then the app freeze. Don't know what the main issue behind it but its only happening when we are using the playback URL of SJMediaCacheServer class.

Implementation of UItableviewCell and UIViewController,

UITableViewCell Code
override func prepareForReuse() {
super.prepareForReuse()
videoUrl = nil
player = nil
playerLayer = nil
playerItem = nil
}

func **setupPlayerView**() {
    player = AVPlayer()
    if let urlString = videoUrl, let url = URL(string: urlString) {
        if let playBackUrl = SJMediaCacheServer.shared().playbackURL(with: url) {
            playerItem = AVPlayerItem(url: playBackUrl)
        } else {
            playerItem = AVPlayerItem(url: url)
        }
    }
    playerLayer = AVPlayerLayer(player: player)
    playerLayer?.frame = view_s1_v1_PlayerView.bounds
    view_s1_v1_PlayerView.layer.addSublayer(playerLayer!)
    player?.replaceCurrentItem(with: playerItem)
}

func **playVideo**() {
    player?.play()

}

func **pauseVideo**() {
    player?.pause()
}

and then play() pause() from UIViewcontroller's

override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
checkVisibleCell()
}

func tableView(_ tableView: UITableView, **didEndDisplaying** cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if let videoCell = cell as? LRVideoMeshTableViewCell {
        videoCell.pauseVideo()
    }
}

func **checkVisibleCell**() {
    let visibleCells = tv_videoCategoryList.visibleCells.compactMap { $0 as? LRVideoMeshTableViewCell }
    
    guard visibleCells.count > 0 else { return }
    
    let visibleFrame = CGRect(x: 0, y: tv_videoCategoryList.contentOffset.y, width: tv_videoCategoryList.bounds.width, height: tv_videoCategoryList.bounds.height)

    let visibleCell = visibleCells
        .filter { visibleFrame.intersection($0.frame).height >= $0.frame.height / 2 }
        .first
    
    visibleCell?.playVideo()
}

@changsanjiang please let me know if I am doing wrong here or suggest if any changes needed in the library to fix this.

Originally posted by @jitesh-sharma in #18 (comment)

prefetchWithURL 预加载 取消task引发的问题

用prefetchWithURL来加载资源, 如果未下载完成前调用task cancel, 然后再次prefetchWithURL加载相同资源,会导致沙盒下载的MP4资源不是完成状态, 虽然提示下载完成了,但是沙盒文件里的文件没办法保存到相册,和导出资源

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.