The simplest ffmpeg-based mobile example: Android Push-to-stream

Source: Internet
Author: User
Tags sprintf
<span id="Label3"></p>This document records an Android platform based on the FFmpeg video streaming device. The source code for the C language of the ejector is derived from the simplest ffmpeg-based push-flow device. The related concepts are no longer duplicated.<br><br>The directory structure of the source code Project. The Java source code is in the SRC directory, and the C code is in the JNI directory.<br><p style="text-align: center;"><p style="text-align: center;"></p></p>The Java-side code for the Android program is located in src\com\leixiaohua1020\sffmpegandroidstreamer\mainactivity.java, as shown below.<br><pre name="code" class="java">/** * Simplest FFmpeg based streaming (rtmp)-android * Simplest FFmpeg android Streamer (rtmp) * * Lei hua Lei Xiaohua * [email protected] * Communication University/digital TV Technology * Communication University of China/digital TV Technology * HTTP://BLOG.CSDN.NET/LEIXIAOHUA1020 * * This program is Ann The simplest ffmpeg-based push-to-flow device on the Android Platform. * It can push video files to the server in the form of streaming Media. * * This software are the simplest streamer based on FFmpeg in ANDROID. * It can stream local media file to streaming media server (in RTMP). * */package Com.leixiaohua1020.sffmpegandroidstreamer;import Android.os.bundle;import android.os.Environment; Import Android.app.activity;import android.util.log;import Android.view.menu;import Android.view.view;import Android.view.view.onclicklistener;import Android.widget.button;import Android.widget.edittext;public Class Mainactivity extends Activity {@Override protected void onCreate (Bundle Savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (r.layout.activity_main); Button Startbutton = (button) This.findviewByid (r.id.button_start); final EditText urledittext_input= (EditText) This.findviewbyid (r.id.input_url); Final EditText urledittext_output= (EditText) This.findviewbyid (r.id.output_url); startbutton.setonclicklistener (new Onclicklistener () {public void OnClick (View arg0) {String folderurl=environment.getexternalstoragedirectory (). GetPath (); String urltext_input=urledittext_input.gettext (). toString (); String inputurl=folderurl+ "/" +urltext_input; String outputurl=urledittext_output.gettext (). toString (); LOG.E ("inputurl", inputurl); LOG.E ("outputurl", outputurl); String info= ""; Stream (inputurl,outputurl); LOG.E ("info", info);}); } @Override public boolean oncreateoptionsmenu (menu Menu) {//inflate The menu, this adds items to the Actio n Bar if it is Present. Getmenuinflater (). Inflate (r.menu.main, menu); Return true; }//jni public native int stream (string inputurl, string OUTPUturl); Static{system.loadlibrary ("avutil-54"); System.loadlibrary ("swresample-1"); System.loadlibrary ("avcodec-56"); System.loadlibrary ("avformat-56"); System.loadlibrary ("swscale-3"); System.loadlibrary ("postproc-53"); System.loadlibrary ("avfilter-5"); System.loadlibrary ("avdevice-56"); System.loadlibrary ("sffstreamer"); } }</pre><br>The C-language side source code is located in jni/simplest_ffmpeg_streamer.c, as shown below.<br><pre name="code" class="cpp">/** * Simplest FFmpeg-based booster-android * simplest FFmpeg android Streamer * * Lei hua Lei Xiaohua * [email protected] * Communication university/digital TV Technology * Communication University of china/digital TV technology * http://blog.csdn.net/leixiaohua1020 * * This program is the simplest under the Android platform based on Ffmpe G's Streaming media push Device. * It can send video data in the form of streaming Media. * * This software are the simplest streamer based on FFmpeg in ANDROID. * It can stream local media file to streaming media server (in RTMP). */#include <stdio.h> #include <time.h> #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" # Include "libavutil/log.h" #ifdef android#include <jni.h> #include <android/log.h> #define LOGE (format, ...) __android_log_print (android_log_error, "(>_<)", format, # #__VA_ARGS__) #define Logi (format, ...) __android_log_print (android_log_info, "(^_^)", format, # #__VA_ARGS__) #else # define LOGE (format, ...) printf ("(>_<)" format "\ n", # #__VA_ARGS__) #define Logi (format, ...) printf ("(^_^)" format "\ n", # #__VA_ARGS__) #endif//output FFmpeg ' s AV_log () void custom_log (void *ptr, int level, const char* fmt, va_list vl) {//to TXT filefile *fp=fopen ("/storage/emulated/0 /av_log.txt "," A + "), if (fp) {vfprintf (fp,fmt,vl); fflush (fp); fclose (fp);} To Logcat//loge (fmt, vl);} Jniexport jint jnicall java_com_leixiaohua1020_sffmpegandroidstreamer_mainactivity_stream (JNIEnv *env, jobject obj, Jstring input_jstr, jstring output_jstr) {avoutputformat *ofmt = NULL; Avformatcontext *ifmt_ctx = null, *ofmt_ctx = null; Avpacket pkt;int ret, i;char input_str[500]={0};char output_str[500]={0};char info[1000]={0};sprintf (input_str, "%s", (*env)->getstringutfchars (env,input_jstr, NULL)) sprintf (output_str, "%s", (*env)->getstringutfchars (env, output_jstr, NULL));//input_str = "cuc_ieschool.flv";//output_str = "rtmp://localhost/publishlive/livestream";// Output_str = "rtp://233.233.233.233:6666";//ffmpeg av_log () callbackav_log_set_callback (custom_log); av_register_ All ();//networkavformat_network_init ();//inputif (ret = Avformat_open_input (&ifmt_ctx, input_str, 0, 0)) < 0) {LOGE ("Could not open input file."); Goto end;} If (ret = Avformat_find_stream_info (ifmt_ctx, 0)) < 0) {LOGE ("Failed to retrieve input stream information"); goto end; }int videoindex=-1;for (i=0; i<ifmt_ctx->nb_streams; i++) if (ifmt_ctx->streams[i]->codec->codec_type ==avmedia_type_video) {videoindex=i;break;} Outputavformat_alloc_output_context2 (&ofmt_ctx, NULL, "flv", output_str); Rtmp//avformat_alloc_output_context2 (&ofmt_ctx, NULL, "mpegts", output_str);//udpif (!ofmt_ctx) {LOGE ("Could Not create output context\n "); ret = Averror_unknown;goto end;} OFMT = ofmt_ctx->oformat;for (i = 0; i < ifmt_ctx->nb_streams; i++) {//create output Avstream according to input Avstreamavstream *in_stream = ifmt_ctx->streams[i]; Avstream *out_stream = Avformat_new_stream (ofmt_ctx, in_stream->codec->codec), if (!out_stream) {LOGE ("Failed Allocating output stream\n "); ret = Averror_unknown;goto end;} Copy the settings of AVCODECCONTEXTRET = avcodec_copy_context (out_stream->codec, in_stream->codec); if (ret < 0) {LOGE ("Failed to Copy-context from I Nput to output stream codec context\n "); goto end;} Out_stream->codec->codec_tag = 0;if (ofmt_ctx->oformat->flags & avfmt_globalheader) out_stream-> Codec->flags |= codec_flag_global_header;} Open Output Urlif (!) ( Ofmt->flags & Avfmt_nofile) {ret = Avio_open (&ofmt_ctx->pb, output_str, avio_flag_write); if (ret < 0) { LOGE ("Could not open output URL '%s '", output_str); Goto end;}} Write file Headerret = Avformat_write_header (ofmt_ctx, NULL), if (ret < 0) {LOGE ("Error occurred when opening output url\n "); Goto end;} int frame_index=0;int64_t start_time=av_gettime (); while (1) {avstream *in_stream, *out_stream;//get an AVPacketret = av_ Read_frame (ifmt_ctx, &pkt); If (ret < 0) break;//fix:no PTS (example:raw h)//simple Write ptsif (pkt.pts==av_ Nopts_value) {//write ptsavrational time_base1=ifmt_ctx->streams[videoindex]->tIme_base;//duration between 2 frames (us) int64_t calc_duration= (double) av_time_base/av_q2d (ifmt_ctx->streams[ videoindex]->r_frame_rate);//parameterspkt.pts= (double) (frame_index*calc_duration)/(double) (av_q2d (time_ Base1) *av_time_base);p kt.dts=pkt.pts;pkt.duration= (double) calc_duration/(double) (av_q2d (time_base1) *av_time_ BASE);} Important:delayif (pkt.stream_index==videoindex) {avrational time_base=ifmt_ctx->streams[videoindex]-> time_base; avrational time_base_q={1,av_time_base};int64_t pts_time = av_rescale_q (pkt.dts, time_base, time_base_q); int64_t now_ Time = Av_gettime ()-start_time;if (pts_time > Now_time) av_usleep (pts_time-now_time);} In_stream = Ifmt_ctx->streams[pkt.stream_index];out_stream = ofmt_ctx->streams[pkt.stream_index];/* copy Packet *///convert pts/dtspkt.pts = av_rescale_q_rnd (pkt.pts, in_stream->time_base, out_stream->time_base, AV_ Round_near_inf| Av_round_pass_minmax);p Kt.dts = av_rescale_q_rnd (pkt.dts, in_stream->time_base, OUT_STREAM-&Gt;time_base, av_round_near_inf| Av_round_pass_minmax);p kt.duration = av_rescale_q (pkt.duration, in_stream->time_base, out_stream->time_base) ;p Kt.pos = -1;//print to screenif (pkt.stream_index==videoindex) {LOGE ("Send%8d video frames to output url\n", Frame_index ); frame_index++;} ret = Av_write_frame (ofmt_ctx, &pkt); ret = av_interleaved_write_frame (ofmt_ctx, &pkt); if (ret < 0) {LOGE ("E Rror muxing packet\n "); Av_free_packet (&pkt);} Write file Trailerav_write_trailer (ofmt_ctx); end:avformat_close_input (&ifmt_ctx);/* close output */if (ofmt_ CTX &&! (ofmt->flags & Avfmt_nofile)) Avio_close (ofmt_ctx->pb), Avformat_free_context (ofmt_ctx), if (ret < 0 && ret! = Averror_eof) {LOGE ("Error occurred.\n "); return-1;} Return 0;}</pre><br>The Android.mk file is located in jni/android.mk, as shown below.<br><pre name="code" class="plain"># android.mk for ffmpeg## Lei Xiaohua Lei hua # [email protected]# http://blog.csdn.net/leixiaohua1020# local_path: = $ (c All My-dir) # FFmpeg Libraryinclude $ (clear_vars) local_module: = Avcodeclocal_src_files: = Libavcodec-56.soinclude $ ( Prebuilt_shared_library) include $ (clear_vars) local_module: = Avdevicelocal_src_files: = Libavdevice-56.soinclude $ ( Prebuilt_shared_library) include $ (clear_vars) local_module: = Avfilterlocal_src_files: = Libavfilter-5.soinclude $ ( Prebuilt_shared_library) include $ (clear_vars) local_module: = Avformatlocal_src_files: = Libavformat-56.soinclude $ ( Prebuilt_shared_library) include $ (clear_vars) local_module: = Avutillocal_src_files: = Libavutil-54.soinclude $ ( Prebuilt_shared_library) include $ (clear_vars) local_module: = Postproclocal_src_files: = Libpostproc-53.soinclude $ ( Prebuilt_shared_library) include $ (clear_vars) local_module: = Swresamplelocal_src_files: = Libswresample-1.soinclude $ (prebuilt_shared_library) include $ (clear_vars) local_module: = swscalelocal_sRc_files: = libswscale-3.soinclude $ (prebuilt_shared_library) # programinclude $ (clear_vars) LOCAL_MODULE: = Sffstreamerlocal_src_files: =simplest_ffmpeg_streamer.clocal_c_includes + = $ (local_path)/includeLOCAL_LDLIBS: =- Llog-lzlocal_shared_libraries: = Avcodec avdevice avfilter avformat avutil postproc swresample swscaleinclude $ (BUILD_SH Ared_library)</pre><br><br>Run results<p><p>The app runs on the phone as shown in the Results.</p></p><p style="text-align: center;"><p style="text-align: center;"><br></p></p><p><p>The video after the push stream can be received on the computer side using ffplay, as shown in.</p></p><p style="text-align: center;"><p style="text-align: center;"><br></p></p><br>Download<p><p><strong><br></strong></p></p><p><p><strong>Simplest FFmpeg Mobile</strong></p></p><br><strong><strong>Project Home</strong></strong><br><p><p>Github:https://github.com/leixiaohua1020/simplest_ffmpeg_mobile</p></p><p><p>Open Source China: https://git.oschina.net/leixiaohua1020/simplest_ffmpeg_mobile</p></p><br>CSDN project: http://download.csdn.net/detail/leixiaohua1020/8924391<br><br>This solution contains various examples of using FFMPEG to process multimedia on the mobile side:<br> <blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"> <blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"> [Android] <br>Simplest_android_player: Android interface-based Video player <br>Simplest_ffmpeg_android_helloworld: ffmpeg-based HelloWorld program under Android platform <br>Simplest_ffmpeg_android_decoder: The simplest ffmpeg-based video decoder on the Android platform <br>Simplest_ffmpeg_android_decoder_onelib: The simplest ffmpeg-based video decoder on the Android Platform-library edition <br> <span style="color:#ff0000;">Simplest_ffmpeg_android_streamer: The simplest ffmpeg-based push-to-flow device under the Android platform</span> <br>Simplest_ffmpeg_android_transcoder: FFmpeg command-line tool ported under Android platform <br>Simplest_sdl_android_helloworld: the simplest program for porting SDL to the Android platform <br>[IOS] <br>Simplest_ios_player: Video player based on iOS interface <br>HelloWorld program based on FFmpeg under the Simplest_ffmpeg_ios_helloworld:ios platform <br>The simplest ffmpeg-based video decoder under the Simplest_ffmpeg_ios_decoder:ios platform <br>The simplest ffmpeg based on the Simplest_ffmpeg_ios_streamer:ios platform <br>FFMPEG.C command-line tool ported under Simplest_ffmpeg_ios_transcoder:ios Platform <br>Simplest_sdl_ios_helloworld: The simplest program to migrate SDL to the iOS platform </blockquote> </blockquote><br><br> <p style="font-size:12px;"><p style="font-size:12px;">Copyright Notice: This article for Bo Master original article, without Bo Master permission not Reproduced.</p></p> <p><p>The simplest ffmpeg-based mobile example: Android Push-to-stream</p></p></span>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.