현재 소켓 서버로 로컬 서버를 구현했습니다. 플레이할 동영상은 제가 짠 로직으로 바이트 배열을 바꿔서 암호화 되어있습니다. 4096 바이트씩 묶어서 암호화 했구요. 하지만 seek을 하게 되면 재생이 되질 않습니다.
아래는 로컬 서버에서 Url로 들어온 요청된 http 헤더에서 range 키 값이 존재하면 실행되는 구문입니다.
protected void execute() {
ExternalResourceDataSource dataSource = new ExternalResourceDataSource(targetFile, context);
long fileSize = dataSource.getContentLength();
String headers = "";
if (cbSkip > 0) {// It is a seek or skip request if there's a Range
// header
headers += "HTTP/1.1 206 Partial Content\r\n";
headers += "Content-Type: " + dataSource.getContentType() + "\r\n";
headers += "Accept-Ranges: bytes\r\n";
headers += "Content-Length: " + (fileSize - cbSkip) + "\r\n";
headers += "Content-Range: bytes " + cbSkip + "-" + (fileSize - 1) + "/" + fileSize + "\r\n";
headers += "Connection: Keep-Alive\r\n";
headers += "\r\n";
} else {
headers += "HTTP/1.1 200 OK\r\n";
headers += "Content-Type: " + dataSource.getContentType() + "\r\n";
headers += "Accept-Ranges: bytes\r\n";
headers += "Content-Length: " + fileSize + "\r\n";
headers += "Connection: Keep-Alive\r\n";
headers += "\r\n";
}
Log.i(TAG, "headers: " + headers);
OutputStream output = null;
int difference = (int) (cbSkip - editSkipBytes(cbSkip));
byte[] buff = new byte[4096];
try {
output = new BufferedOutputStream(client.getOutputStream(), 30 * 1024);
output.write(headers.getBytes());
FileInputStream data = (FileInputStream) dataSource.getInputStream();
int cbRead;
if (cbSkip > 0) {
data.skip(editSkipBytes(cbSkip));
data.read(buff, 0, buff.length);
enDecryptVideo.combineByteArray(buff);
output.write(buff, difference, buff.length);
while (!client.isClosed() && (cbRead = data.read(buff, 0, buff.length)) != -1) {
enDecryptVideo.combineByteArray(buff);
output.write(buff, 0, cbRead);
}
} else if (cbSkip == 0) {
dataSource.skipFully(data, cbSkip);//try to skip as much as possible
// Loop as long as there's stuff to send and client has not closed
while (!client.isClosed() && (cbRead = data.read(buff, 0, buff.length)) != -1) {
enDecryptVideo.combineByteArray(buff);
output.write(buff, 0, cbRead);
}
}
} catch (SocketException socketException) {
Log.e(TAG, "SocketException() thrown, proxy client has probably closed. This can exit harmlessly");
} catch (Exception e) {
Log.e(TAG, "Exception thrown from streaming task:");
Log.e(TAG, e.getClass().getName() + " : " + e.getLocalizedMessage());
}
// Cleanup
try {
if (output != null) {
output.close();
}
client.close();
} catch (IOException e) {
Log.e(TAG, "IOException while cleaning up streaming task:");
Log.e(TAG, e.getClass().getName() + " : " + e.getLocalizedMessage());
e.printStackTrace();
}
}
private long editSkipBytes(long cbSkip) {
return cbSkip / 4096 * 4096;
}
enDecryptVideo.combineByteArray(buff); 는 매개변수로 들어온 바이트 배열을 로직에 의해서 바이트 배열을 바꿔주는 역할을 합니다.
skip된 바이트 가 4096의 배수가 아니기 때문에 이를 처리해서 스트림해줘야 하고 그 뒤부터는 4096씩 가져와서 복호화해 스트림해줍니다. 제가 짠 로직에 어떤 오류가 있어서 재생이 되지 않을까요... 부탁드립니다.