부검: La Sopa de Videos
Pues bien,este es mi primer post que escribo para esta plata forma,sin 금수,primero perm ítanme presentarme.
Mi nombre es Marco Ramírez y soy un Desarrollador Android con 4 a ños de experiencea del Estado de México(트라네펜트라 콘크리트).그는 Java와 Kotlin para varios 거래처에서 프로젝트 매니저를 맡고 있다.También he trabajado con flatter para desarrollo de apps para Android y iOS(mejor conocidas como apps híbridas).
회사 명🍺 y disfruto de hacer videos para mi canal de YouTube(espero retomarlo pronto,pues el trabajo se ha incrementado).Pueden은 mi canal y ver mis streamings as í como futuros videos sobre ingenier í a de software를 사용합니다.
매실, suficiente de presentaciones, vamos al-grano.
Recientemente,me ha tocado armar una aplicación de video bajo demanda(VoD por sus siglas en inglés).Esta app la armépara mostrar las capacidaides de un servidor multimedia:ANT Media Server y me encantaría contarles cómo me fue:D.
Una 앱 영상 팟캐스트?
Empecemos por definir una app VOD a nivel técnico.
Una app de este tipo lo que hace es distribuir contenido en video bajo demanda del usuario por medio de un servicdor multimedia que aloja el contenido en el mismo y es distribuido por diversos protocolo.El más conocido es El HLS que tiene compatibilidad con la gran mayoría de los dispositivos de hoy en día.
La app VOD se encarga de recibir Dico contenido como un request común y corriente y lo Distributuye a un Replicator de video Integrato a La aplicación.En estos casos,los Replicattores podemos Encorlarlos En Web(con Javascript)y En Components nativos de Android y iOS.
?Quénos encontramos?
Primeramente,necesitamos tener en cuenta varias cosas con ANT Media Server.
ANT es bastante amigable desde el concepto en que su licencia comunitaria es completamente graties y tiene muchísimas bonddes para poder armar plataformas para streaming incluída la transmisión vía RTMP.Igalmente si asíse desea el streaming se puede dejar para grabar en el disco del servidor.
Igualmente,al ser comunitario el server,tiene sus propios scripts para que puedas poner tus certificados SSL sin problemas con Certbot y asítransportar tus contenidos por HTTPS.
Hay otras cualidades como el compatir tu streaming en Facebook y YouTube,sin 금수 estas yason de paga,pero por 69달러 almes o 1400달러 de forma permanente,siento que vale la pena si quieres tener tu propio sistema de streaming.
?Cómo puedo Arlo?
Por tiempo,ahorita tuve que ocupar una imagen de DigitalOcean que tenía el software precargado y ya todo dispues to para poder servir la aplicación in mediatamente.Uséuna droplet de 5달러 con Ubuntu 20.04 LTS y hasta ahorita me ha corrido sin ning ún problema.De hecho puedo mostrar las gráficas De estosúltimos días:
중앙 프로세서
안코 데반다
Esto ha sido probado con muy poquitos usuarios.Por lo que se debe de tomar en cuenta como en cualquier app el número estimado de usuarios que vayan a consumirla,pues en base a ello tenemos que poner la infrastructure:3.
Igualmente,les dejo en esteenlace 유엔 튜토리얼 파라포더 instalarlo desde cualquier servidor con Ubuntu.
Ahora,para comunicar el servidor multimedia con la app,uséFirebase para poder Interunicar los datos de cada uno de los videos con la app.Dentro de este tenemos el Realtime Database donde pude montar el“esquema de base de datos”.La estructura es más o menos así:
movies
|
|- 0
|- moviedb_id: Integer (ID de MovieDB)
|- name: String (nombre del video)
|- poster_uri: String
|- protagonists: ArrayList<String> (se declaran dentro de este nodo)
|- uri: String (URL del video)
Ya con esto y al implementar los servicios de Firebase en mi app,puedo usar el siguiente código para poder llamar a los datos:private fun fetchMovies() {
val database = Firebase.database
val myRef = database.getReference("movies")
movieItems = ArrayList()
myRef.addValueEventListener(object: ValueEventListener{
override fun onCancelled(error: DatabaseError) {
Log.w("App", "Failed to read value.", error.toException())
}
override fun onDataChange(snapshot: DataSnapshot) {
for(item: DataSnapshot in snapshot.children) {
var protagonists = ArrayList<String>();
for(protagonistItem in item.child("protagonists").children) {
protagonists.add(protagonistItem.value.toString())
}
val movieItem = MovieItem(item.child("moviedb_id").value.toString(), item.child("name").value.toString(),
item.child("uri").value.toString(),
item.child("poster_uri").value.toString(), protagonists)
movieItems.add(movieItem)
}
initRecyclerView(movieItems)
}
})
}
Ahora en la app?quénos encontramos?
El MediaController
Primeramente,nos encontramos que en Android usamos el component e VideoView para poder reproductir el video que nosotros le entregemos.Pero lo primero que nos encontramos es que el VideoView carece de cualquier control.escomo en JS que ya tiene todo en el mismo CONTENDOR, por lo que tienes que ponerle un MEDIA CONTROLLER가 없습니다.
El Media Controller es quien se va a encargar de poner los clásicos botones de Play, Rewind, FF 등 y controlar El streaming.El código para implementar en Kotlin es El siguiente:
val mediaController = MediaController(requireContext(), true)
mediaController.setAnchorView(videoView)
videoView.setOnPreparedListener(OnPreparedListener { mediaController.show(0) })
videoView.setVideoPath(arguments?.getString("uri"))
videoView.setMediaController(mediaController)
videoView.start()
Al implementar este snippet ya podremos controlar nuestros controles en el VideoView y poder manejar la reproduction ción del video.De poner en Portrait la pantalla y otras deficultades。。。
Otro tema que podemos llegar a encontrarnos es el poner la interfaz en landscape y regresarla a 초상화alsalir del reproductor.Meestuve quebrando un poco la cabeza pues al-usar 내비게이션 컨트롤러, toda la navegación se hace des de una sola Activity,sin 금수 es algo que no se pueda solucionar.
Dentro del onCreateView haz lo siguiente:
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
requireActivity().window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
requireActivity().window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
requireActivity().window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
requireActivity().window.statusBarColor = Color.TRANSPARENT;
return inflater.inflate(R.layout.fragment_video_player, container, false)
}
Igualmente en el fragmento front a este, debes implementar en el onResume el siguiente có digo para regresar a modo 초상화:override fun onResume() {
super.onResume()
val activity = requireActivity() as AppCompatActivity
activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
activity.supportActionBar!!.show()
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
activity.window.statusBarColor = resources.getColor(R.color.colorPrimaryDark)
activity.window.setFlags(
WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
activity.window.decorView.systemUiVisibility = 0
}
Ya con esto,se hizo un workflow un poco más estable.La navegabilidad básica ya es historia contada en muchos posts jejejeje(어댑터, 뉴스 회수, 네비게이션 컨트롤러, RESTAPI 등).Próximante(si el trabajo y mis actividades lo permiten)les traerémás contenido.쿠스그?
Ahorita la verdad el código lo hice muy rápido por lo que me gustaría hacer un poco más amigable al desarrollador el mismo y ya montarle inclusive MVVM y otras buenas prácticas que por tiempo no pude montar asícomo:
즐거운 인코딩!!!
P、 D:Lam entablemente no pude poner screenshots de la app por motivos de confidencialidad,pero próximamente puedo hacer incluso un release más estable.
Reference
이 문제에 관하여(부검: La Sopa de Videos), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/rzerostern/post-mortem-la-sopa-de-videos-2e0o텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)