Open GoogleCodeExporter opened 9 years ago
Shouldn't be a problem-- It was designed to work outside streambaby. (although I
haven't tried it in a while...)
There are actually two main classes (both of which require several support
classes):
JavaMP4Splitter
CPortMP4Splitter
Both classes inherit from InputStream so once you create an object from them you
simply treat it as an open MP4 stream.
CPortMP4Splitter is based on the original port of mod_h264_streaming. This was
the
original code Streambaby used. There were some small issues however, and the
code
was hard to maintain because it was a straight-C port without much
understanding.
JavaMP4Splitter is what is currently used and is was based on straight Java code
written by Cahoon: http://code.google.com/p/mp4splitter/ It may be a better
bet.
It will require (at a minimum the following support classes): MP4Streamer and
mp4.util.*. It may require a few other support classes, but without trying to
break
it out myself I'm not sure what they may be, and I think they hopefully just a
couple
standalone classes.
It may be better to discuss this on the main streambaby support thread over at
tivocommunity:
http://tivocommunity.com/tivo-vb/showthread.php?t=416858
Original comment by kearygri...@gmail.com
on 30 Sep 2009 at 10:16
Thanks a lot for your very valuable feedback. I have followed your suggestions
and played around with
JavaMP4Splitter. As you said, only a few support classes are needed. I have,
however, run into a conceptual
problem and also have an administrative question.
Let's start with the latter. I think it would be nice if streambaby provided
the H264 HTTP Pseudo-Streaming
feature out-of-the-box, without me hacking something together based on a
checkout of your current code -
which will not benefit from any changes you make to the project. I see two ways
to achieve this: Either we
slightly adapt the code in the streambaby repository so that one can simply use
the streambaby JAR, or I set
up a new project on Google Code that uses SVN externals in appropriate
subdirectories of the project to
include the necessary Java files from your repository. What is your opinion?
In any case, I think the following change is needed: JavaMP4Splitter.java,
NamedStream.java, and
SocketProcessInputStream.java have a tight dependency on
com.unwiredappeal.tivo.utils.Log. If one (like me)
does not want to use this particular logging mechanism, you have a problem. One
way out would be to
convert Log.java to an interface and add a setter setLog(Log) to these classes.
Not so nice but it allows for
injection. Maybe you see another way?
The second question is technical: I see that the JavaMP4Splitter.Splitter class
creates a new thread and after a
first glimpse this looks like some producer-consumer pattern. When I use
JavaMP4Splitter to deliver a file via
Jersey REST Web Service, I run into IOExceptions thrown by the
out.write(input, 0, read);
call in MdatAtom's
public void writeData(DataOutput out) throws IOException
method. A closer inspection shows that the PipedInputStream is closed (closed
by reader). I am not sure
whether this is due to a bug in my code but more importantly, I am not sure
whether starting a new thread is
a good idea/necessary at all in my setting. Do you see clearer here? Could one
add an option to disable the
creation of the thread?
I see in your code,
final PipedOutputStream po = new PipedOutputStream(pi);
// writeSplitMp4(new DataOutputStream(po));
(new Thread()
{
@Override
public void run()
{
try
{
writeSplitMp4(new DataOutputStream(po));
po.close();
}
catch (IOException e)
{
Log.error("IOException: " + e);
try
{
po.close();
}
catch (IOException e1)
{
}
}
}
}).start();
that you once tried it without the thread but uncommenting this and commenting
out the thread creation
blocks for me.
Best,
Kaspar
P.S. My project is a Maven project and thus relatively easy to use; let me know
if you need it already now.
P.P.S. By the way: the following files are needed:
com/unwiredappeal/mediastreams/mp4/JavaMP4Splitter.java
com/unwiredappeal/mediastreams/mp4/MP4Streamer.java
#com/unwiredappeal/mediastreams/mp4/StreamableMP4.java
com/unwiredappeal/sample/rest/MovieRestService.java
com/unwiredappeal/tivo/utils/AccessibleByteArrayOutputStream.java
com/unwiredappeal/tivo/utils/AvailableSocket.java
com/unwiredappeal/tivo/utils/BitInputStream.java
com/unwiredappeal/tivo/utils/EasySSLHelper.java
com/unwiredappeal/tivo/utils/Log.java
com/unwiredappeal/tivo/utils/NamedStream.java
com/unwiredappeal/tivo/utils/Persistent.java
com/unwiredappeal/tivo/utils/PersistentHashTable.java
com/unwiredappeal/tivo/utils/PropertyReplacer.java
com/unwiredappeal/tivo/utils/RandomAccessFileInputStream.java
com/unwiredappeal/tivo/utils/RandomAccessInputStream.java
com/unwiredappeal/tivo/utils/SimpleCookieManager.java
com/unwiredappeal/tivo/utils/SocketProcessInputStream.java
com/unwiredappeal/tivo/utils/TempFileManager.java
com/unwiredappeal/tivo/utils/Utils.java
com/unwiredappeal/tivo/utils/WordWrap.java
mp4/util/atom/AppleMetaAtom.java
mp4/util/atom/Atom.java
mp4/util/atom/AtomError.java
mp4/util/atom/AtomException.java
mp4/util/atom/AtomVisitor.java
mp4/util/atom/Avc1Atom.java
mp4/util/atom/AvcCAtom.java
mp4/util/atom/ByteStream.java
mp4/util/atom/CdscAtom.java
mp4/util/atom/ChapAtom.java
mp4/util/atom/Co64Atom.java
mp4/util/atom/ContainerAtom.java
mp4/util/atom/CttsAtom.java
mp4/util/atom/DataAtom.java
mp4/util/atom/DefaultAtomVisitor.java
mp4/util/atom/DinfAtom.java
mp4/util/atom/DrefAtom.java
mp4/util/atom/EdtsAtom.java
mp4/util/atom/ElstAtom.java
mp4/util/atom/FreeAtom.java
mp4/util/atom/FtypAtom.java
mp4/util/atom/GmhdAtom.java
mp4/util/atom/HdlrAtom.java
mp4/util/atom/HintAtom.java
mp4/util/atom/HybridAtom.java
mp4/util/atom/IMhdAtom.java
mp4/util/atom/IodsAtom.java
mp4/util/atom/ITrefTypeAtom.java
mp4/util/atom/LeafAtom.java
mp4/util/atom/MdatAtom.java
mp4/util/atom/MdhdAtom.java
mp4/util/atom/MdiaAtom.java
mp4/util/atom/MinfAtom.java
mp4/util/atom/moov/udta/meta/ilst/AARTAtom.java
mp4/util/atom/moov/udta/meta/ilst/CatgAtom.java
mp4/util/atom/moov/udta/meta/ilst/CovrAtom.java
mp4/util/atom/moov/udta/meta/ilst/CpilAtom.java
mp4/util/atom/moov/udta/meta/ilst/CprtalbAtom.java
mp4/util/atom/moov/udta/meta/ilst/CprtartAtom.java
mp4/util/atom/moov/udta/meta/ilst/CprtAtom.java
mp4/util/atom/moov/udta/meta/ilst/CprtcmtAtom.java
mp4/util/atom/moov/udta/meta/ilst/CprtdayAtom.java
mp4/util/atom/moov/udta/meta/ilst/CprtgenAtom.java
mp4/util/atom/moov/udta/meta/ilst/CprtgrpAtom.java
mp4/util/atom/moov/udta/meta/ilst/CprtlyrAtom.java
mp4/util/atom/moov/udta/meta/ilst/CprtnamAtom.java
mp4/util/atom/moov/udta/meta/ilst/CprttooAtom.java
mp4/util/atom/moov/udta/meta/ilst/CprtwrtAtom.java
mp4/util/atom/moov/udta/meta/ilst/DescAtom.java
mp4/util/atom/moov/udta/meta/ilst/DiskAtom.java
mp4/util/atom/moov/udta/meta/ilst/EgidAtom.java
mp4/util/atom/moov/udta/meta/ilst/GnreAtom.java
mp4/util/atom/moov/udta/meta/ilst/KeywAtom.java
mp4/util/atom/moov/udta/meta/ilst/PcstAtom.java
mp4/util/atom/moov/udta/meta/ilst/PurdAtom.java
mp4/util/atom/moov/udta/meta/ilst/PurlAtom.java
mp4/util/atom/moov/udta/meta/ilst/RtngAtom.java
mp4/util/atom/moov/udta/meta/ilst/StikAtom.java
mp4/util/atom/moov/udta/meta/ilst/TrknAtom.java
mp4/util/atom/moov/udta/meta/ilst/TvenAtom.java
mp4/util/atom/moov/udta/meta/ilst/TvesAtom.java
mp4/util/atom/moov/udta/meta/ilst/TvnnAtom.java
mp4/util/atom/moov/udta/meta/ilst/TvshAtom.java
mp4/util/atom/moov/udta/meta/ilst/TvsnAtom.java
mp4/util/atom/moov/udta/meta/IlstAtom.java
mp4/util/atom/moov/udta/MetaAtom.java
mp4/util/atom/MoovAtom.java
mp4/util/atom/MvhdAtom.java
mp4/util/atom/SmhdAtom.java
mp4/util/atom/StblAtom.java
mp4/util/atom/StcoAtom.java
mp4/util/atom/StscAtom.java
mp4/util/atom/StsdAtom.java
mp4/util/atom/StssAtom.java
mp4/util/atom/StszAtom.java
mp4/util/atom/SttsAtom.java
mp4/util/atom/TimeToSampleAtom.java
mp4/util/atom/TkhdAtom.java
mp4/util/atom/TrakAtom.java
mp4/util/atom/TrefAtom.java
mp4/util/atom/UdtaAtom.java
mp4/util/atom/UnknownAtom.java
mp4/util/atom/VmhdAtom.java
mp4/util/Mp4Dump.java
mp4/util/Mp4InterleaveWriter.java
mp4/util/MP4Log.java
mp4/util/Mp4Parser.java
mp4/util/Mp4Split.java
Original comment by kaspar.f...@gmail.com
on 3 Oct 2009 at 9:02
After looking & thinking a bit it may make sense to just rely on mp4.util.* (+ a
couple of extra classes) instead of starting from JavaMP4Splitter.java.
JavaMP4Splitter may change as streambaby evolves (I consider it more part of the
streambaby framework than the MP4 framework).
I just pushed up a new class to SVN Mp4Test.java that shows how to use
mp4.util.* to
copy a split Mp4 file. (The main class takes "src.mp4 dst.mp4
splitPosInSeconds").
The mp4.util classes have no logging dependencies (they already use an injection
method to set the logger). So the only dependencies you have are:
mp4.util.*
com.unwiredappeal.tivo.utils.RandomAccessInputStream
com.unwiredappeal.tivo.utils.RandomAccessFileInputStream
About the threading in the original example, the threading is required.
PipedInputStream and PipedOutputStream are required to run in different threads
(and
you get errors like you describe if they aren't...)
Even if you use just the mp4.util classes I think you will find you need to do
something similar-- mp4.util was originally written to output it's contents to
a
stream (which is what you will see Mp4Test doing). However to "serve" up a MP4
file
it should act more as an InputStream. I accomplished this in streambaby using
the
PipedInputStream and PipedOutputStream classes running in seperate threads.
As far as how to deal with SVN and seperate projects using the code, I'm not
really
sure how to deal with it for the moment. I think it makes sense to wait and
see how
things go and then deal with it.
Original comment by kearygri...@gmail.com
on 4 Oct 2009 at 5:37
Original issue reported on code.google.com by
kaspar.f...@gmail.com
on 30 Sep 2009 at 7:45