דילוג לתוכן
  • חוקי הפורום
  • פופולרי
  • לא נפתר
  • משתמשים
  • חיפוש גוגל בפורום
  • צור קשר
עיצובים
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • ברירת מחדל (ללא עיצוב (ברירת מחדל))
  • ללא עיצוב (ברירת מחדל)
כיווץ
מתמחים טופ
  1. דף הבית
  2. אנדרואיד - כללי
  3. בניית ופיתוח אפליקציות
  4. עזרה הדדית - בניית ופיתוח אפליקציות
  5. עזרה | כתיבת קוד קוטלין עבור ספריית RootEncoder

עזרה | כתיבת קוד קוטלין עבור ספריית RootEncoder

מתוזמן נעוץ נעול הועבר עזרה הדדית - בניית ופיתוח אפליקציות
4 פוסטים 3 כותבים 65 צפיות 3 עוקבים
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
תגובה
  • תגובה כנושא
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • איש אמתא מנותק
    איש אמתא מנותק
    איש אמת
    מדריכים
    כתב נערך לאחרונה על ידי איש אמת
    #1

    היי שלום
    אני מחפש מפתח קוטלין שיודע לעבוד עם ספריית RootEncoder (ספריית סטרימינג) שרת OME ורכיב מצלמה
    דרושים לי הדברים הבאים:
    1 כתיבת ה layout של המסך עם רכיבי המצלמה (כפתורים תצוגה קדימה וכד׳)
    2 כתיבת קוד קוטלין שמטפל בכל הרכיבים במסך ומזרים את התשדיר לשרת OME
    יש לי כרגע קוד של המסך אבל אני לא מצליח להבין למה הוא מורח את הצילום על כל המסך ולמה כשאני מסובב את המכשיר התמונה מתעוותת
    אני משלם 200₪ על התוצאה שאני רוצה
    אני אשמח גם אם סתם יעזרו לי כאן
    יש כאן דוגמה לקוד שיש לי כרגע:

    layout:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/black"
        tools:context=".ui.streaming.StreamingFragment">
    
        <SurfaceView
            android:id="@+id/surfaceView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent" />
    
        <TextView
            android:id="@+id/tv_bitrate"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:textColor="@android:color/white"
            android:background="#80000000"
            android:padding="8dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:text="1200 Kbps" />
    
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            app:layout_constraintBottom_toBottomOf="parent">
    
            <ImageView
                android:id="@+id/settings_button"
                android:layout_width="64dp"
                android:layout_height="64dp"
                android:src="@drawable/ic_settings"
                android:background="?attr/selectableItemBackgroundBorderless"
                app:tint="@color/white"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toStartOf="@id/b_start_stop"
                app:layout_constraintHorizontal_chainStyle="spread_inside" />
    
            <ImageView
                android:id="@+id/b_start_stop"
                android:layout_width="80dp"
                android:layout_height="80dp"
                android:src="@drawable/stream_icon"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toEndOf="@id/settings_button"
                app:layout_constraintEnd_toStartOf="@id/switch_camera" />
    
            <ImageView
                android:id="@+id/switch_camera"
                android:layout_width="64dp"
                android:layout_height="64dp"
                android:src="@drawable/switch_icon"
                android:background="?attr/selectableItemBackgroundBorderless"
                app:tint="@color/white"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toEndOf="@id/b_start_stop" />
        </androidx.constraintlayout.widget.ConstraintLayout>
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    קוטלין:

    package com.iam699030.tore.ui.streaming
    
    import android.Manifest
    import android.content.pm.PackageManager
    import android.os.Build
    import android.os.Bundle
    import android.util.Log
    import android.view.*
    import android.widget.Toast
    import androidx.activity.result.contract.ActivityResultContracts
    import androidx.appcompat.app.AlertDialog
    import androidx.core.content.ContextCompat
    import androidx.fragment.app.Fragment
    import com.google.android.material.dialog.MaterialAlertDialogBuilder
    import com.google.android.material.textfield.TextInputEditText
    import com.iam699030.tore.R
    import com.iam699030.tore.databinding.FragmentStreamingBinding
    import com.pedro.common.ConnectChecker
    import com.pedro.library.rtmp.RtmpCamera1
    import java.util.*
    
    class StreamingFragment : Fragment(), ConnectChecker, SurfaceHolder.Callback {
    
        private var _binding: FragmentStreamingBinding? = null
        private val binding get() = _binding!!
        private lateinit var rtmpCamera1: RtmpCamera1
    
        private val permissionLauncher = registerForActivityResult(
            ActivityResultContracts.RequestMultiplePermissions()
        ) { permissions ->
            val allGranted = permissions.entries.all { it.value }
            if (allGranted) {
                // אם ניתנו הרשאות, אפשר להתחיל תצוגה מקדימה
                rtmpCamera1.startPreview()
            } else {
                Toast.makeText(requireContext(), "נדרשות הרשאות מצלמה ואודיו", Toast.LENGTH_SHORT).show()
            }
        }
    
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
            _binding = FragmentStreamingBinding.inflate(inflater, container, false)
            return binding.root
        }
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            // אתחול המצלמה והמאזין לתצוגה
            rtmpCamera1 = RtmpCamera1(binding.surfaceView, this)
            binding.surfaceView.holder.addCallback(this)
            setupListeners()
            requestPermissions()
        }
    
        private fun requestPermissions() {
            if (!hasPermissions()) {
                permissionLauncher.launch(REQUIRED_PERMISSIONS)
            }
        }
    
        private fun hasPermissions(): Boolean {
            return REQUIRED_PERMISSIONS.all {
                ContextCompat.checkSelfPermission(requireContext(), it) == PackageManager.PERMISSION_GRANTED
            }
        }
    
        private fun setupListeners() {
            binding.bStartStop.setOnClickListener {
                if (!rtmpCamera1.isStreaming) {
                    showLessonNameDialog()
                } else {
                    rtmpCamera1.stopStream()
                    binding.bStartStop.setImageResource(R.drawable.stream_icon)
                    binding.tvBitrate.text = ""
                }
            }
            binding.switchCamera.setOnClickListener {
                try {
                    rtmpCamera1.switchCamera()
                } catch (e: Exception) {
                    Toast.makeText(requireContext(), e.message, Toast.LENGTH_SHORT).show()
                }
            }
        }
    
        private fun showLessonNameDialog() {
            val dialogView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_lesson_name, null)
            val editText = dialogView.findViewById<TextInputEditText>(R.id.dialogLessonNameEditText)
            MaterialAlertDialogBuilder(requireContext())
                .setTitle("הזן שם לשיעור")
                .setView(dialogView)
                .setNegativeButton("ביטול", null)
                .setPositiveButton("התחל שידור") { _, _ ->
                    val lessonName = editText.text.toString().trim()
                    if (lessonName.isNotEmpty()) {
                        startStream(lessonName)
                    }
                }
                .show()
        }
    
        private fun startStream(lessonName: String) {
            if (!rtmpCamera1.isRecording) {
                if (rtmpCamera1.prepareAudio() && rtmpCamera1.prepareVideo()) {
                    val hostIp = "10.0.2.2"
                    val rtmpUrl = "rtmp://$hostIp:1935/app/$lessonName"
                    rtmpCamera1.startStream(rtmpUrl)
                    binding.bStartStop.setImageResource(R.drawable.stream_stop_icon)
                } else {
                    Toast.makeText(requireContext(), "שגיאה בהכנת השידור", Toast.LENGTH_SHORT).show()
                }
            }
        }
    
        // --- מימוש ConnectChecker ---
        override fun onConnectionSuccess() {
            activity?.runOnUiThread { Toast.makeText(requireContext(), "התחברות הצליחה", Toast.LENGTH_SHORT).show() }
        }
    
        override fun onConnectionFailed(reason: String) {
            activity?.runOnUiThread {
                Toast.makeText(requireContext(), "התחברות נכשלה: $reason", Toast.LENGTH_SHORT).show()
                rtmpCamera1.stopStream()
                binding.bStartStop.setImageResource(R.drawable.stream_icon)
            }
        }
    
        override fun onNewBitrate(bitrate: Long) {
            activity?.runOnUiThread { binding.tvBitrate.text = "${bitrate / 1024} Kbps" }
        }
    
        override fun onDisconnect() {
            activity?.runOnUiThread {
                Toast.makeText(requireContext(), "התנתק", Toast.LENGTH_SHORT).show()
                binding.bStartStop.setImageResource(R.drawable.stream_icon)
            }
        }
        override fun onAuthError() {}
        override fun onAuthSuccess() {}
        override fun onConnectionStarted(url: String) {}
    
        // --- מימוש SurfaceHolder.Callback ---
        override fun surfaceCreated(holder: SurfaceHolder) {}
    
        override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
            // ★★★ מתחילים את התצוגה המקדימה רק כאן, כשהמידות סופיות ★★★
            rtmpCamera1.startPreview()
        }
    
        override fun surfaceDestroyed(holder: SurfaceHolder) {
            if (rtmpCamera1.isStreaming) rtmpCamera1.stopStream()
            rtmpCamera1.stopPreview()
        }
    
        override fun onDestroyView() {
            super.onDestroyView()
            _binding = null
        }
    
        companion object {
            private val REQUIRED_PERMISSIONS = mutableListOf(
                Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA,
            ).apply {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                    this.add(Manifest.permission.POST_NOTIFICATIONS)
                }
            }.toTypedArray()
        }
    }
    

    אני יודע שאני חושב שאני יודע.

    I תגובה 1 תגובה אחרונה
    0
    • איש אמתא איש אמת

      היי שלום
      אני מחפש מפתח קוטלין שיודע לעבוד עם ספריית RootEncoder (ספריית סטרימינג) שרת OME ורכיב מצלמה
      דרושים לי הדברים הבאים:
      1 כתיבת ה layout של המסך עם רכיבי המצלמה (כפתורים תצוגה קדימה וכד׳)
      2 כתיבת קוד קוטלין שמטפל בכל הרכיבים במסך ומזרים את התשדיר לשרת OME
      יש לי כרגע קוד של המסך אבל אני לא מצליח להבין למה הוא מורח את הצילום על כל המסך ולמה כשאני מסובב את המכשיר התמונה מתעוותת
      אני משלם 200₪ על התוצאה שאני רוצה
      אני אשמח גם אם סתם יעזרו לי כאן
      יש כאן דוגמה לקוד שיש לי כרגע:

      layout:

      <?xml version="1.0" encoding="utf-8"?>
      <androidx.constraintlayout.widget.ConstraintLayout
          xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto"
          xmlns:tools="http://schemas.android.com/tools"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:background="@android:color/black"
          tools:context=".ui.streaming.StreamingFragment">
      
          <SurfaceView
              android:id="@+id/surfaceView"
              android:layout_width="0dp"
              android:layout_height="0dp"
              app:layout_constraintTop_toTopOf="parent"
              app:layout_constraintBottom_toBottomOf="parent"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintEnd_toEndOf="parent" />
      
          <TextView
              android:id="@+id/tv_bitrate"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_margin="16dp"
              android:textColor="@android:color/white"
              android:background="#80000000"
              android:padding="8dp"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintTop_toTopOf="parent"
              tools:text="1200 Kbps" />
      
          <androidx.constraintlayout.widget.ConstraintLayout
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:layout_margin="16dp"
              app:layout_constraintBottom_toBottomOf="parent">
      
              <ImageView
                  android:id="@+id/settings_button"
                  android:layout_width="64dp"
                  android:layout_height="64dp"
                  android:src="@drawable/ic_settings"
                  android:background="?attr/selectableItemBackgroundBorderless"
                  app:tint="@color/white"
                  app:layout_constraintTop_toTopOf="parent"
                  app:layout_constraintBottom_toBottomOf="parent"
                  app:layout_constraintStart_toStartOf="parent"
                  app:layout_constraintEnd_toStartOf="@id/b_start_stop"
                  app:layout_constraintHorizontal_chainStyle="spread_inside" />
      
              <ImageView
                  android:id="@+id/b_start_stop"
                  android:layout_width="80dp"
                  android:layout_height="80dp"
                  android:src="@drawable/stream_icon"
                  app:layout_constraintTop_toTopOf="parent"
                  app:layout_constraintBottom_toBottomOf="parent"
                  app:layout_constraintStart_toEndOf="@id/settings_button"
                  app:layout_constraintEnd_toStartOf="@id/switch_camera" />
      
              <ImageView
                  android:id="@+id/switch_camera"
                  android:layout_width="64dp"
                  android:layout_height="64dp"
                  android:src="@drawable/switch_icon"
                  android:background="?attr/selectableItemBackgroundBorderless"
                  app:tint="@color/white"
                  app:layout_constraintTop_toTopOf="parent"
                  app:layout_constraintBottom_toBottomOf="parent"
                  app:layout_constraintEnd_toEndOf="parent"
                  app:layout_constraintStart_toEndOf="@id/b_start_stop" />
          </androidx.constraintlayout.widget.ConstraintLayout>
      </androidx.constraintlayout.widget.ConstraintLayout>
      

      קוטלין:

      package com.iam699030.tore.ui.streaming
      
      import android.Manifest
      import android.content.pm.PackageManager
      import android.os.Build
      import android.os.Bundle
      import android.util.Log
      import android.view.*
      import android.widget.Toast
      import androidx.activity.result.contract.ActivityResultContracts
      import androidx.appcompat.app.AlertDialog
      import androidx.core.content.ContextCompat
      import androidx.fragment.app.Fragment
      import com.google.android.material.dialog.MaterialAlertDialogBuilder
      import com.google.android.material.textfield.TextInputEditText
      import com.iam699030.tore.R
      import com.iam699030.tore.databinding.FragmentStreamingBinding
      import com.pedro.common.ConnectChecker
      import com.pedro.library.rtmp.RtmpCamera1
      import java.util.*
      
      class StreamingFragment : Fragment(), ConnectChecker, SurfaceHolder.Callback {
      
          private var _binding: FragmentStreamingBinding? = null
          private val binding get() = _binding!!
          private lateinit var rtmpCamera1: RtmpCamera1
      
          private val permissionLauncher = registerForActivityResult(
              ActivityResultContracts.RequestMultiplePermissions()
          ) { permissions ->
              val allGranted = permissions.entries.all { it.value }
              if (allGranted) {
                  // אם ניתנו הרשאות, אפשר להתחיל תצוגה מקדימה
                  rtmpCamera1.startPreview()
              } else {
                  Toast.makeText(requireContext(), "נדרשות הרשאות מצלמה ואודיו", Toast.LENGTH_SHORT).show()
              }
          }
      
          override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
              _binding = FragmentStreamingBinding.inflate(inflater, container, false)
              return binding.root
          }
      
          override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
              super.onViewCreated(view, savedInstanceState)
              // אתחול המצלמה והמאזין לתצוגה
              rtmpCamera1 = RtmpCamera1(binding.surfaceView, this)
              binding.surfaceView.holder.addCallback(this)
              setupListeners()
              requestPermissions()
          }
      
          private fun requestPermissions() {
              if (!hasPermissions()) {
                  permissionLauncher.launch(REQUIRED_PERMISSIONS)
              }
          }
      
          private fun hasPermissions(): Boolean {
              return REQUIRED_PERMISSIONS.all {
                  ContextCompat.checkSelfPermission(requireContext(), it) == PackageManager.PERMISSION_GRANTED
              }
          }
      
          private fun setupListeners() {
              binding.bStartStop.setOnClickListener {
                  if (!rtmpCamera1.isStreaming) {
                      showLessonNameDialog()
                  } else {
                      rtmpCamera1.stopStream()
                      binding.bStartStop.setImageResource(R.drawable.stream_icon)
                      binding.tvBitrate.text = ""
                  }
              }
              binding.switchCamera.setOnClickListener {
                  try {
                      rtmpCamera1.switchCamera()
                  } catch (e: Exception) {
                      Toast.makeText(requireContext(), e.message, Toast.LENGTH_SHORT).show()
                  }
              }
          }
      
          private fun showLessonNameDialog() {
              val dialogView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_lesson_name, null)
              val editText = dialogView.findViewById<TextInputEditText>(R.id.dialogLessonNameEditText)
              MaterialAlertDialogBuilder(requireContext())
                  .setTitle("הזן שם לשיעור")
                  .setView(dialogView)
                  .setNegativeButton("ביטול", null)
                  .setPositiveButton("התחל שידור") { _, _ ->
                      val lessonName = editText.text.toString().trim()
                      if (lessonName.isNotEmpty()) {
                          startStream(lessonName)
                      }
                  }
                  .show()
          }
      
          private fun startStream(lessonName: String) {
              if (!rtmpCamera1.isRecording) {
                  if (rtmpCamera1.prepareAudio() && rtmpCamera1.prepareVideo()) {
                      val hostIp = "10.0.2.2"
                      val rtmpUrl = "rtmp://$hostIp:1935/app/$lessonName"
                      rtmpCamera1.startStream(rtmpUrl)
                      binding.bStartStop.setImageResource(R.drawable.stream_stop_icon)
                  } else {
                      Toast.makeText(requireContext(), "שגיאה בהכנת השידור", Toast.LENGTH_SHORT).show()
                  }
              }
          }
      
          // --- מימוש ConnectChecker ---
          override fun onConnectionSuccess() {
              activity?.runOnUiThread { Toast.makeText(requireContext(), "התחברות הצליחה", Toast.LENGTH_SHORT).show() }
          }
      
          override fun onConnectionFailed(reason: String) {
              activity?.runOnUiThread {
                  Toast.makeText(requireContext(), "התחברות נכשלה: $reason", Toast.LENGTH_SHORT).show()
                  rtmpCamera1.stopStream()
                  binding.bStartStop.setImageResource(R.drawable.stream_icon)
              }
          }
      
          override fun onNewBitrate(bitrate: Long) {
              activity?.runOnUiThread { binding.tvBitrate.text = "${bitrate / 1024} Kbps" }
          }
      
          override fun onDisconnect() {
              activity?.runOnUiThread {
                  Toast.makeText(requireContext(), "התנתק", Toast.LENGTH_SHORT).show()
                  binding.bStartStop.setImageResource(R.drawable.stream_icon)
              }
          }
          override fun onAuthError() {}
          override fun onAuthSuccess() {}
          override fun onConnectionStarted(url: String) {}
      
          // --- מימוש SurfaceHolder.Callback ---
          override fun surfaceCreated(holder: SurfaceHolder) {}
      
          override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
              // ★★★ מתחילים את התצוגה המקדימה רק כאן, כשהמידות סופיות ★★★
              rtmpCamera1.startPreview()
          }
      
          override fun surfaceDestroyed(holder: SurfaceHolder) {
              if (rtmpCamera1.isStreaming) rtmpCamera1.stopStream()
              rtmpCamera1.stopPreview()
          }
      
          override fun onDestroyView() {
              super.onDestroyView()
              _binding = null
          }
      
          companion object {
              private val REQUIRED_PERMISSIONS = mutableListOf(
                  Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA,
              ).apply {
                  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                      this.add(Manifest.permission.POST_NOTIFICATIONS)
                  }
              }.toTypedArray()
          }
      }
      

      I מנותק
      I מנותק
      I believe
      כתב נערך לאחרונה על ידי
      #2

      @איש-אמת
      @לא-מתייאש אלוף בקוטלין

      101100001 תגובה 1 תגובה אחרונה
      1
      • I I believe

        @איש-אמת
        @לא-מתייאש אלוף בקוטלין

        101100001 מנותק
        101100001 מנותק
        10110000
        כתב נערך לאחרונה על ידי
        #3

        @I-believe ולא יעשה את זה בשביל 200 ₪ 😊

        איש אמתא תגובה 1 תגובה אחרונה
        1
        • 101100001 10110000

          @I-believe ולא יעשה את זה בשביל 200 ₪ 😊

          איש אמתא מנותק
          איש אמתא מנותק
          איש אמת
          מדריכים
          כתב נערך לאחרונה על ידי
          #4

          @10110000 אתה תעשה?
          ואם לא כמה כן הוא יקח?

          אני יודע שאני חושב שאני יודע.

          תגובה 1 תגובה אחרונה
          0

          • התחברות

          • אין לך חשבון עדיין? הרשמה

          • התחברו או הירשמו כדי לחפש.
          • פוסט ראשון
            פוסט אחרון
          0
          • חוקי הפורום
          • פופולרי
          • לא נפתר
          • משתמשים
          • חיפוש גוגל בפורום
          • צור קשר