Video upload and streaming Record video – Android camera – Looxcie Upload video – http put –...

Preview:

Citation preview

Video upload and streaming

• Record video– Android camera– Looxcie

• Upload video– http put– Thread

• Video streaming– Streaming server– Video formatting– Playing a video stream

Record video

• Recording with phone’s camera is in another lecture

• Looxcie – records video and holds it in the camera. – Looxcie app pulls the video from camera to phone

ftp package• New app – VideoStreamer

– Add user permission: Internet• ftp package

– Download apache commons.net package from• http://commons.apache.org/net/download_net.cgi

– Get binary

– Decompress– Add package

• Right on the src directory of the newly made app• Select build path -> configure build path • Click add external jar. • Browse to commons-net-2.2.jar• Select “Order and Export” tab• Click commons-net-2.2.jar

Using ftp

• Make new class, FTPHelper• Add member function, uploadFile

– FTPClient ftpClient = new FTPClient();– ftpClient.connect( "128.4.35.59" );– ftpClient.login( "ftpuser", "ftpuser" );– System.out.println("Connected to 128.4.35.59");– System.out.print(ftpClient.getReplyString());– BufferedInputStream buffIn = null;– buffIn = new BufferedInputStream(new

FileInputStream("/mnt/sdcard/my_mov.mp4"));– result = ftpClient.storeFile("my_vov.mp4", buffIn);– if (result) {

• Log.e("DebugInfo","ftp trasnfer returned true");

– } else {• Log.e("DebugInfo","ftp trasnfer returned false");

– }

In VideoStreamer class

• At the end of onCreate, add– FTP ftp = new FTP();– ftp.uploadFile();

• Run

• If the file is very large, this will fail because the UI thread cannot take too long

• You must use theads

threads

• asyncTask - easy threads• In VideoStreamer class, add new class– private class UploadFileTask extends AsyncTask {}– Let eclipse add unimplemented methods

• Move from onCreate to doInBackground– FTP ftp = new FTP();– ftp.uploadFile();

• In onCreate, add– new UploadFileTask().execute();

• Run.

Video Server

• Popular video servers– Darwin• Apple version• Open source version• Supports many formats including quicktime• I couldn’t get it working on windows

– Wowza• Not open source• Free (for a small number of users/downloaders)

Try it

• Take video with phone• Pull file from phone (in

/mnt/sdcard/DCIM/Camera/*.3gp)• Put file in

– C:\Program Files (x86)\Wowza Media Systems\Wowza Media Server 2.2.3\content

• Open VLC– Select menu: media -> network stream– enter rtsp://128.4.35.53:1935/vod/mp4:Vid3.mp4– Where Vid3.mp4 is the name

• Does not work

Streaming Video Format

• It is not always possible to stream a video captured by any video camera

• Wowza Media Server and Flash only support H.264 (AVC1, MPEG4 Part 10), AAC (MP4A, AAC, AAC+, HE-AAC) and MP3 in an MP4 file.– http://www.wowzamedia.com/forums/content.php?107-

GSpot-Tool-to-inspect-MP4-%28QuickTime-container%29-video-audio-codecs

• The format can be checked– Gspot: http://www.headbands.com/gspot/– Shows the format details

transcoding• MS Expression can also make video files that can be streamed. But this requires manual

effort, whereas ffmpeg can be run from command line or a script

• Ffmpeg can be used to transcode – read a video file compressed in one set of codecs and recompress in another set

• Transcoding is very slow– Works better if the source is low bit-rate. On phone video, select low rate

• Using ffmpeg is tricky– The following perl code transcode.pl

• #!/usr/bin/perl• d:\\uploadedContent\\ffmpeg\\bin\\ffmpeg.exe -i $ARGV[0] -strict experimental -acodec aac -ab 32k -vcodec

libx264 -fpre libx264-medium.ffpreset -b 512k $ARGV[0].mp4

– Call via>> perl transode.pl filename.3gp– These parameters can be adjusted– Try it:

• Take video with camera• Pull from phone, move to directory where ffmpeg is located (might need to copy FFPreset files to this directory)• Run perl code

– Wait

• Move file to directory• View with vlc

Video streaming on android

• Change the VideoStreaming Activity so that it – implements SurfaceHolder.Callback

• Add member variables– private SurfaceView mPreview;– private SurfaceHolder holder;– private MediaPlayer mMediaPlayer;

• Add surface view to layout. Call it SurfaceView• At the end of onCreate,

– mPreview = (SurfaceView) findViewById(R.id.SurfaceView);– holder = mPreview.getHolder();– holder.addCallback(this);– holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

• Add button, StartVideo• Add callback

– Button startButton = (Button)findViewById(R.id.StartVideo);– startButton.setOnClickListener(new View.OnClickListener() {});– In onClick, add

• playVideo();

• Make public void playVideo() {– if (mMediaPlayer != null) {– mMediaPlayer.release();– mMediaPlayer = null;– }– mMediaPlayer = new MediaPlayer();– //mMediaPlayer.setDataSource("/mnt/sdcard/DCIM/Camera/VID_20110502_143808.3gp"); // some file– mMediaPlayer.setDataSource("rtsp://128.4.35.53:1935/vod/mp4:Vid3.mp4"); // some stream– //mMediaPlayer.setDataSource("rtsp://128.4.35.53:1935/vod/mp4:sample.mp4");– mMediaPlayer.setDisplay(holder);– mMediaPlayer.prepare();– mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);– mMediaPlayer.start();

• Run– It takes a long time. But should run

improvements• Lots of things can be improved with callbacks• Put progress bar to give the user feedback as video is starting• In layout, add ProgressBar• Add member variable

– ProgressBar progressBar;• In onCreate,

– progressBar = (ProgressBar)findViewById(R.id.ProgressBar01);– progressBar.setVisibility(View.INVISIBLE);

• In playVideo– At the beginning, add progressBar.setVisibility(View.VISIBLE);– After mMediaPlayer = new MediaPlayer();, add

• mMediaPlayer.setOnPreparedListener(new OnPreparedListener() {});• In onPrepared, add

– progressBar.setVisibility(View.INVISIBLE);– mMediaPlayer.start();

– Change mMediaPlayer.prepare(); to• mMediaPlayer.prepareAsync();

– Remove mMediaPlayer.start();

• Now run, and progress bar shows that something is happening• But if an error occurs, the progress bar never stops

– Need to add more callbacks• setOnErrorListener(android.media.MediaPlayer.OnErrorListener) to catch errors• setOnCompletionListener(OnCompletionListener)., when it finished, to clean up screen or something• setOnBufferingUpdateListener to track the buffer, this gives a percent