Giter Site home page Giter Site logo

jeffvideocache's Issues

怎么支持多音轨切换?

比如我的M3U8文件是这样的:
#EXTM3U
#EXT-X-VERSION:7
#EXT-X-STREAM-INF:BANDWIDTH=128000,CODECS="mp4a.40.34"
000_00000.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=320000,CODECS="mp4a.40.34"
001_00000.m3u8

这是两个音轨
我如何使用JeffVideoCache在这两个音轨间切换呢?

多段缓存时,Mp4CacheTask.getRequestRange() 返回的分段问题

当有多段缓存时,Mp4CacheTask.getRequestRange() 返回的分段会忽略一部分已经缓存的分段。
以下图为例,当一个视频具有三段缓存时,如果 position 在 cache1 和 cache2 之间,则最终返回的分段的起点为 position,终点为 cache3 的起点,cache2 会被忽略,被再缓存一次。

ProblemOfGetRequestRange

以我目前的理解,正确的返回值应该是 VideoRange(finalStart, firstEnd),即起点为 position,终点为 cache2 的起点。缓存完这一段后,Mp4VideoCacheThread.notifyOnCacheRangeCompleted()会被调用去缓存下一段,补上所有的“洞”。

demo换成mp4视频无法播放

大佬,我又来了。。。

我在demo apk中换了好些个mp4连接,都无法成功播放..
测试连接:

https://vdse.bdstatic.com//e52b1ca2bcaef6e01a346135f63a7a66.mp4?authorization=bce-auth-v1%2F40f207e648424f47b2e3dfbb1014b1a5%2F2021-06-23T15%3A20%3A04Z%2F-1%2Fhost%2F409b0d7a837ac9c76c0aa04ac6f197d22accb63137cdb2884166d74198892d6d

我看了大佬你的一些文章,可能是这个问题造成的。因为我发现已经下载的部分也无法打开..
image

有些有文件内版权信息的视频,会让ijkPlayer发出多次http请求,这时咱们的代理就会卡住,界面视频一直loading

这里是测试用的视频:
链接: https://pan.baidu.com/s/1XzZSpA5NBzMzlwdR98xwxA?pwd=9m16 提取码: 9m16 复制这段内容后打开百度网盘手机App,操作更方便哦

下面是我测试抓取的日志信息:
2023-01-16 14:47:20.145 17675-19649/cn.kuwo.player I/SocketProcessTask: SocketProcessTask 创建: 37770
2023-01-16 14:47:20.145 17675-19666/cn.kuwo.player I/SocketProcessTask: sRequestCountAtomic : 1
2023-01-16 14:47:20.147 17675-19666/cn.kuwo.player D/SocketProcessTask: 请求URL:/aHR0cDovL2FyLnBsYXllci5yZjAxLnN5Y2RuLmt1d28uY24vN2M5N2I3ZmZlOGZkNDk1MmE4Mjk1YjRiM2ViYjQxZjkvNjNjNGYyZjgvcmVzb3VyY2UvbTIvNjMvOTIvMjQ0MjEyNTI5Ny5tcDQmamVmZm1vbnlfdmlkZW8mbm9uX20zdTgmamVmZm1vbnlfdmlkZW8mMzk0NDczMV83X01QNCZqZWZmbW9ueV92aWRlbyZ1bmtub3du
2023-01-16 14:47:20.147 17675-19666/cn.kuwo.player D/SocketProcessTask: 请求Method:GET
2023-01-16 14:47:20.147 17675-19666/cn.kuwo.player D/SocketProcessTask: 请求KeepAlive:false
2023-01-16 14:47:20.147 17675-19666/cn.kuwo.player D/SocketProcessTask: 请求Header:remote-addr:127.0.0.1
2023-01-16 14:47:20.147 17675-19666/cn.kuwo.player D/SocketProcessTask: 请求Header:icy-metadata:1
2023-01-16 14:47:20.147 17675-19666/cn.kuwo.player D/SocketProcessTask: 请求Header:http-client-ip:127.0.0.1
2023-01-16 14:47:20.147 17675-19666/cn.kuwo.player D/SocketProcessTask: 请求Header:host:127.0.0.1:42053
2023-01-16 14:47:20.147 17675-19666/cn.kuwo.player D/SocketProcessTask: 请求Header:range:bytes=0-
2023-01-16 14:47:20.147 17675-19666/cn.kuwo.player D/SocketProcessTask: 请求Header:connection:close
2023-01-16 14:47:20.147 17675-19666/cn.kuwo.player D/SocketProcessTask: 请求Header:user-agent:Lavf/57.83.100
2023-01-16 14:47:20.147 17675-19666/cn.kuwo.player D/SocketProcessTask: 请求Header:accept:/
2023-01-16 14:47:20.147 17675-19666/cn.kuwo.player D/SocketProcessTask: request.parseRequest end
2023-01-16 14:47:20.147 17675-19666/cn.kuwo.player D/SocketProcessTask: request url=http://werewrewt2442125297.mp4
2023-01-16 14:47:20.147 17675-19666/cn.kuwo.player D/SocketProcessTask: http://42125297.mp4
non_m3u8
unknown
2023-01-16 14:47:20.148 17675-19666/cn.kuwo.player D/SocketProcessTask: request mSocket-->37770
2023-01-16 14:47:20.159 17675-19649/cn.kuwo.player I/SocketProcessTask: SocketProcessTask 创建: 37772
2023-01-16 14:47:20.159 17675-19667/cn.kuwo.player I/SocketProcessTask: sRequestCountAtomic : 2
2023-01-16 14:47:20.160 17675-19667/cn.kuwo.player D/SocketProcessTask: 请求URL:/aHR0cDovL2FyLnBsYXllci5yZjAxLnN5Y2RuLmt1d28uY24vN2M5N2I3ZmZlOGZkNDk1MmE4Mjk1YjRiM2ViYjQxZjkvNjNjNGYyZjgvcmVzb3VyY2UvbTIvNjMvOTIvMjQ0MjEyNTI5Ny5tcDQmamVmZm1vbnlfdmlkZW8mbm9uX20zdTgmamVmZm1vbnlfdmlkZW8mMzk0NDczMV83X01QNCZqZWZmbW9ueV92aWRlbyZ1bmtub3du
2023-01-16 14:47:20.160 17675-19667/cn.kuwo.player D/SocketProcessTask: 请求Method:GET
2023-01-16 14:47:20.160 17675-19667/cn.kuwo.player D/SocketProcessTask: 请求KeepAlive:false
2023-01-16 14:47:20.160 17675-19667/cn.kuwo.player D/SocketProcessTask: 请求Header:remote-addr:127.0.0.1
2023-01-16 14:47:20.160 17675-19667/cn.kuwo.player D/SocketProcessTask: 请求Header:icy-metadata:1
2023-01-16 14:47:20.160 17675-19667/cn.kuwo.player D/SocketProcessTask: 请求Header:http-client-ip:127.0.0.1
2023-01-16 14:47:20.160 17675-19667/cn.kuwo.player D/SocketProcessTask: 请求Header:host:127.0.0.1:42053
2023-01-16 14:47:20.160 17675-19667/cn.kuwo.player D/SocketProcessTask: 请求Header:range:bytes=22100255-
2023-01-16 14:47:20.160 17675-19667/cn.kuwo.player D/SocketProcessTask: 请求Header:connection:close
2023-01-16 14:47:20.160 17675-19667/cn.kuwo.player D/SocketProcessTask: 请求Header:user-agent:Lavf/57.83.100
2023-01-16 14:47:20.160 17675-19667/cn.kuwo.player D/SocketProcessTask: 请求Header:accept:/
2023-01-16 14:47:20.160 17675-19667/cn.kuwo.player D/SocketProcessTask: request.parseRequest end
2023-01-16 14:47:20.160 17675-19667/cn.kuwo.player D/SocketProcessTask: request url=http://n
2023-01-16 14:47:20.160 17675-19667/cn.kuwo.player D/SocketProcessTask: http://42125297.mp4
non_m3u8
unknown
2023-01-16 14:47:20.160 17675-19667/cn.kuwo.player D/SocketProcessTask: request mSocket-->37772
2023-01-16 14:47:20.163 17675-19666/cn.kuwo.player W/System.err: at cn.kuwo.cache.socket.SocketProcessTask.run(SocketProcessTask.java:82)
2023-01-16 14:47:20.163 17675-19666/cn.kuwo.player E/SocketProcessTask: socket request failed, exception=cn.kuwo.cache.common.VideoCacheException: send response failed:
2023-01-16 14:47:20.163 17675-19666/cn.kuwo.player W/SocketProcessTask: finally Socket solve count = 1

忽略了一种切片suffix情况,望修复

你好,在查阅您的代码后,发现M3U8Seg类中对切片进行了suffix判断,其中忽略了一些重定向的链接并没有后缀,因此需要在最后添加默认.ts

改了一下getRequestRange

当resume的时候,里面只有一个分段,且start是0,end是文件长度,此时会得到一个新的start和end都为文件长度的range,这样会报错,望大佬采纳

image

parseRequest请求一直报错,请大佬看看

IJKpalyer播放器播放时,一直有错误打印,就是这个HttpRequest.parseRequest,明明请求失败了,但是却又有响应M3U8SegRespons,很奇怪

E/libOpenSLES: frameworks/wilhelm/src/android/AudioPlayer_to_android.cpp:1197: pthread_mutex_lock_timeout_np returned 110
I/M3U8CacheTask: startDownloadSegTask index=15, url=http://cdn.hainvyou.com/20220117/HQCVcfUf/800kb/hls/bh2MVpba.ts
I/IJKMEDIA: Opening 'http://127.0.0.1:43252/aHR0cDovL2Nkbi5tYWludnlvdS5jb20vMjAyMjAxMTcvSFFDVmNmVWYvaW5kZXgubTN1OCZqZWZmbW9ueV9zZWcmaHR0cDovL2Nkbi5tYWludnlvdS5jb20vMjAyMjAxMTcvSFFDVmNmVWYvODAwa2IvaGxzL0llM29nald3LnRzJmplZmZtb255X3NlZyYvNjVkNWJlYzU1NGMyNjRjY2UwMDMzMzYxZGI4MTExMWYvMS50cyZqZWZmbW9ueV9zZWcmdW5rbm93bg' for reading
I/tv.danmaku.ijk.media.player.IjkMediaPlayer: onNativeInvoke 1
W/System.err: java.net.SocketException: Can't read inputStream
W/System.err: at com.owen.tv91.player.videocache.socket.request.HttpRequest.parseRequest(HttpRequest.java:69)
W/System.err: at com.owen.tv91.player.videocache.socket.SocketProcessTask.run(SocketProcessTask.java:43)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
W/SocketProcessTask: socket request failed, exception=java.net.SocketException: Can't read inputStream
I/SocketProcessTask: finally Socket solve count = 1
I/tv.danmaku.ijk.media.player.IjkMediaPlayer: onNativeInvoke 131073
I/tv.danmaku.ijk.media.player.IjkMediaPlayer: onNativeInvoke 131074
I/SocketProcessTask: sRequestCountAtomic : 2
D/SocketProcessTask: request url=http://cdn.hainvyou.com/20220117/HQCVcfUf/index.m3u8&jeffmony_seg&http://cdn.hainvyou.com/20220117/HQCVcfUf/800kb/hls/Ie3ogjWw.ts&jeffmony_seg&/65d5bec554c264cce0033361db81111f/1.ts&jeffmony_seg&unknown
http://cdn.hainvyou.com/20220117/HQCVcfUf/index.m3u8
http://cdn.hainvyou.com/20220117/HQCVcfUf/800kb/hls/Ie3ogjWw.ts
/65d5bec554c264cce0033361db81111f/1.ts
unknown
I/M3U8SegResponse: SegFilePath=/storage/emulated/0/Android/data/com.owen.tv91/files/Video/jeffmony/65d5bec554c264cce0033361db81111f/1.ts
I/M3U8SegResponse: index=1, parentUrl=http://cdn.hainvyou.com/20220117/HQCVcfUf/index.m3u8, segUrl=http://cdn.hainvyou.com/20220117/HQCVcfUf/800kb/hls/Ie3ogjWw.ts
I/M3U8CacheTask: startDownloadSegTask index=16, url=http://cdn.hainvyou.com/20220117/HQCVcfUf/800kb/hls/eT4tl0JI.ts
I/tv.danmaku.ijk.media.player.IjkMediaPlayer: onNativeInvoke 2
D/M3U8SegResponse: FileLength=600472, segLength=0, FilePath=/storage/emulated/0/Android/data/com.owen.tv91/files/Video/jeffmony/65d5bec554c264cce0033361db81111f/1.ts
D/M3U8SegResponse: Send M3U8 ts file end, this=com.owen.tv91.player.videocache.socket.response.M3U8SegResponse@15185347
I/M3U8CacheTask: startDownloadSegTask index=17, url=http://cdn.hainvyou.com/20220117/HQCVcfUf/800kb/hls/j8N36jCp.ts
W/System.err: java.net.SocketException: Can't read inputStream
at com.owen.tv91.player.videocache.socket.request.HttpRequest.parseRequest(HttpRequest.java:69)
at com.owen.tv91.player.videocache.socket.SocketProcessTask.run(SocketProcessTask.java:43)
W/System.err: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
I/IJKMEDIA: Opening 'http://127.0.0.1:43252/aHR0cDovL2Nkbi5tYWludnlvdS5jb20vMjAyMjAxMTcvSFFDVmNmVWYvaW5kZXgubTN1OCZqZWZmbW9ueV9zZWcmaHR0cDovL2Nkbi5tYWludnlvdS5jb20vMjAyMjAxMTcvSFFDVmNmVWYvODAwa2IvaGxzL3k2UERrYVNhLnRzJmplZmZtb255X3NlZyYvNjVkNWJlYzU1NGMyNjRjY2UwMDMzMzYxZGI4MTExMWYvMi50cyZqZWZmbW9ueV9zZWcmdW5rbm93bg' for reading
W/System.err: at java.lang.Thread.run(Thread.java:818)
W/SocketProcessTask: socket request failed, exception=java.net.SocketException: Can't read inputStream
I/SocketProcessTask: finally Socket solve count = 1
I/tv.danmaku.ijk.media.player.IjkMediaPlayer: onNativeInvoke 1
I/tv.danmaku.ijk.media.player.IjkMediaPlayer: onNativeInvoke 131073
I/tv.danmaku.ijk.media.player.IjkMediaPlayer: onNativeInvoke 131074
D/IJKMEDIA: FFP_MSG_VIDEO_SIZE_CHANGED: 1280, 720
D/IJKMEDIA: SDL_VoutFFmpeg_CreateOverlay(w=1280, h=720, fmt=RV32(0x32335652, dp=0xb06c8da0)
I/SocketProcessTask: sRequestCountAtomic : 2
D/SocketProcessTask: request url=http://cdn.hainvyou.com/20220117/HQCVcfUf/index.m3u8&jeffmony_seg&http://cdn.hainvyou.com/20220117/HQCVcfUf/800kb/hls/y6PDkaSa.ts&jeffmony_seg&/65d5bec554c264cce0033361db81111f/2.ts&jeffmony_seg&unknown
D/SocketProcessTask: http://cdn.hainvyou.com/20220117/HQCVcfUf/index.m3u8
http://cdn.hainvyou.com/20220117/HQCVcfUf/800kb/hls/y6PDkaSa.ts
/65d5bec554c264cce0033361db81111f/2.ts
unknown
I/M3U8SegResponse: SegFilePath=/storage/emulated/0/Android/data/com.owen.tv91/files/Video/jeffmony/65d5bec554c264cce0033361db81111f/2.ts
index=2, parentUrl=http://cdn.hainvyou.com/20220117/HQCVcfUf/index.m3u8, segUrl=http://cdn.hainvyou.com/20220117/HQCVcfUf/800kb/hls/y6PDkaSa.ts
I/tv.danmaku.ijk.media.player.IjkMediaPlayer: onNativeInvoke 2
D/M3U8SegResponse: FileLength=281248, segLength=0, FilePath=/storage/emulated/0/Android/data/com.owen.tv91/files/Video/jeffmony/65d5bec554c264cce0033361db81111f/2.ts
D/M3U8SegResponse: Send M3U8 ts file end, this=com.owen.tv91.player.videocache.socket.response.M3U8SegResponse@39b1d540
D/IJKMEDIA: ANativeWindow_setBuffersGeometry: w=580, h=326, f=�(0x1) => w=1280, h=720, f=RV32(0x32335652)
D/IJKMEDIA: FFP_MSG_VIDEO_SIZE_CHANGED: 1280, 720
W/System.err: java.net.SocketException: Can't read inputStream
I/IJKMEDIA: Opening 'http://127.0.0.1:43252/aHR0cDovL2Nkbi5tYWludnlvdS5jb20vMjAyMjAxMTcvSFFDVmNmVWYvaW5kZXgubTN1OCZqZWZmbW9ueV9zZWcmaHR0cDovL2Nkbi5tYWludnlvdS5jb20vMjAyMjAxMTcvSFFDVmNmVWYvODAwa2IvaGxzLzBhemhGc3ZlLnRzJmplZmZtb255X3NlZyYvNjVkNWJlYzU1NGMyNjRjY2UwMDMzMzYxZGI4MTExMWYvMy50cyZqZWZmbW9ueV9zZWcmdW5rbm93bg' for reading
W/System.err: at com.owen.tv91.player.videocache.socket.request.HttpRequest.parseRequest(HttpRequest.java:69)
at com.owen.tv91.player.videocache.socket.SocketProcessTask.run(SocketProcessTask.java:43)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
W/SocketProcessTask: socket request failed, exception=java.net.SocketException: Can't read inputStream
I/SocketProcessTask: finally Socket solve count = 1

看了一下源码,不知道是不是和这while循环有关,正常流程是不是也要关闭socket
public void run() {
try {
//....................................
while(!mSocket.isClosed()) { // 修改方式1:这里改成if
request.parseRequest();
BaseResponse response;
//....................................
if (TextUtils.equals(ProxyCacheUtils.M3U8, videoTypeInfo)) {
response = new M3U8Response(request, videoUrl, headers, currentTime);
} else if (TextUtils.equals(ProxyCacheUtils.NON_M3U8, videoTypeInfo)) {
response = new Mp4Response(request, videoUrl, headers, currentTime);
} else {
//无法从已知的信息判定视频信息,需要重新请求
//....................................
} else if (url.contains(ProxyCacheUtils.SEG_PROXY_SPLIT_STR)) {
//说明是M3U8 ts格式的文件
//....................................
} else {
throw new VideoCacheException("Local Socket Error url");
}
/*******************************************************************************
ProxyCacheUtils.close(mSocket); // 修改方式2:这里响应之后得关闭该socket
********************************************************************************/
}

	} catch (Exception e) {
		e.printStackTrace();
		LogUtils.w(TAG,"socket request failed, exception=" + e);
	} finally {
		ProxyCacheUtils.close(outputStream);
		ProxyCacheUtils.close(inputStream);
		ProxyCacheUtils.close(mSocket);
		int count = sRequestCountAtomic.decrementAndGet();
		LogUtils.i(TAG, "finally Socket solve count = " + count);
	}
}

}

Mp4CacheTask.getRequestRange() 逻辑困惑

当 mVideoRangeMap 为空时,为什么从 0 开始缓存,而不是从 position 开始缓存

public VideoRange getRequestRange(long position) {
  if (mVideoRangeMap.size() == 0) {
      return new VideoRange(0, mTotalSize);
  }
  ...
}

重大BUG。视频seek在最后,再往回seek到中间,数据出错,播放器无法播放。

分析后发现问题出在这里。
类 Mp4Response.java
方法 public void sendBody(Socket socket, OutputStream outputStream, long pending) throws Exception{

}
如下代码
while (bufferLength > 0 && (readLength = randomAccessFile.read(buffer, 0, (int) bufferLength)) != -1) {
offset += readLength;
outputStream.write(buffer, 0, readLength);
randomAccessFile.seek(offset);
bufferLength = (avilable - offset + 1) > bufferedSize ? bufferedSize : (avilable - offset + 1);
}
这里判断条件有问题。当第一次seek到结尾的时候,缓存文件中前面段没写入的数据,此段数据为空数据,再次往回seek,此时read 后,readLength 长度不是-1,但向buffer数组中写入的全是0,播放器接受到的全是空数据,也跳不出while循环。

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.